簡體   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