繁体   English   中英

Flask - 不能在 app/__init__.py 中使用实例 celery?

[英]Flask - Cannot use instance celery into app/__init__.py?

我已经访问了社区中的几个问题,但我认为这是我的错,因为我无法确定一个合适的方法,在使用 Flask 文档中指出的工厂架构模式。

我们有一个基于Flask + Gunicorn + Nginx的应用程序,它总是在没有重大挑战的情况下工作。 但是,我们需要构建一个需要异步任务的解决方案。 很快,指示一致,为此使用 Celery,但甚至遵循此处使用的样式。

我无法编译项目,因为它通知存在导入错误,并且框架的官方文档并没有明确说明如何在结构工厂中使用它,只是如何在单个实例中进行操作。

我该如何解决这个问题?

我的追溯:

  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()

这是由循环导入引起的。 实际问题是导入api.py最终会导入您的 Celery 任务。 由于您在定义celery实例之前执行from .api import configure ,这打破了循环依赖。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM