烧瓶-无法将实例芹菜用于app / __ init__.py?

时间:2020-01-31 09:35:18

标签: python flask design-patterns celery

我已经在社区中拜访了几个问题,但是我相信这是我的错,因为在使用documentation Flask中指示的工厂体系结构模式时,我无法确定适当的方法。

我们有一个基于 Flask + Gunicorn + Nginx 的应用程序,该应用程序始终运行无大挑战。但是,我们需要构建一个需要异步任务的解决方案。 很快迹象表明,为此使用Celery,但即使遵循here的样式也是如此。

我无法编译项目,因为它会告知存在导入错误,并且官方documentation of the framework并未在结构工厂中清楚说明如何使用它,而只是如何单独进行实例。

我该如何解决?

我的追溯:

  File "/home/user/Workspace/test/project_async/celery_runner.py", line 3, in <module>
    from app import create_app
  File "/home/user/Workspace/test/project_async/app/__init__.py", line 9, in <module>
    from .api import configure as config_api
  File "/home/user/Workspace/test/project_async/app/api.py", line 3, in <module>
    from .resources.chosen import Change
  File "/home/user/Workspace/test/project_async/app/resources/chosen.py", line 5, in <module>
    from app.jobs.tasks import exec_change as tk_change
  File "/home/user/Workspace/test/project_async/app/jobs/tasks.py", line 1, in <module>
    from app import celery
ImportError: cannot import name 'celery' from 'app' (/home/user/Workspace/test/project_async/app/__init__.py)

我的结构

.
├── app
│   ├── api.py
│   ├── jobs
│   │   ├── celeryconfig.py
│   │   ├── __init__.py
│   │   └── tasks.py
│   ├── jwt.py
│   ├── models
│   │   ├── core.py
│   │   ├── __init__.py
│   │   ├── inventory.py
│   │   └── other.py
│   ├── resources
│   │   ├── chosen.py
│   │   └── __init__.py
│   ├── schemas.py
│   ├── services
│   │   ├── chosen.py
│   │   ├── base.py
│   │   ├── chosen_other.py
│   │   └── inventory.py
│   ├── static
│   │   ├── swagger.json
│   │   └── swagger.yaml
│   ├── swagger.py
│   └── utils.py
├── celery_runner.py
├── config.py
├── main.py
├── test.log
└── tests
    ├── __init__.py
    └── test_inventory.py

代码:

路径-app / __ init __。py

from flask import Flask
from flask_cors import CORS
from flask_migrate import Migrate

from config import configure as config_project

from .api import configure as config_api
from .jwt import configure as config_jwt
from .models.core import configure as config_db
from .models.inventory import configure as config_db_mongo
from .swagger import configure as config_docs
from celery import Celery

celery = Celery(__name__)

def create_app(config_name):

    app = Flask(__name__)

    '''Added Configurations'''
    config_project(app)
    config_jwt(app)
    config_api(app)
    config_docs(app)
    config_db(app)
    config_db_mongo(app)
    '''Added Thirds'''
    CORS(app)
    Migrate(app, app.db)
    '''Background Tasks'''
    celery.conf.update(app.config)
    celery.config_from_object('app.jobs.celeryconfig')

    return app

路径-project_async / celery_worker.py

from dotenv import find_dotenv, load_dotenv

from app import create_app

load_dotenv(find_dotenv())

app = create_app(getenv('FLASK_ENV') or 'default')
app.app_context().push()

路径-app / jobs / celeryconfig.py

broker_url = 'redis://localhost:6379/1'
result_backend = 'redis://localhost:6379/0'

# import
imports = 'app.jobs.tasks'

# Timezone
timezone = 'America/Bogota'
enable_utc = True

路径-app / jobs / tasks.py

from app import celery
from app.services.chosen_other import ChangeOpportunity


@celery.task(name='tasks.change')
def exec_change(data, change, client):
    change = ChangeOpportunity(data, change, client)
    change.execute_change()

1 个答案:

答案 0 :(得分:0)

这是由循环进口引起的。实际的问题是,导入api.py最终会导致导入Celery任务。由于您在定义from .api import configure实例之前正在执行celery,所以这与循环依赖关系中断了。

您应该尝试重新组织代码,以便导入一个模块不需要导入许多其他模块。如果查看堆栈跟踪,可以看到api.py导入了resources/chosen.py,而jobs/tasks.py也导入了。所有的交叉包装导入都是必需的吗?

请尝试分解更复杂的模块,以免没有所有这些间接导入。