Python中使用Flask工厂模式创建app并配置Celery,如何解决循环import问题?
要让 Celery 服务在 Flask app 的上下文中生效,就须要在 Flask 工厂模式中创建 celery 服务,在具体业务中再 import 。
如果在 Flask 创建 app 之前,就生成 celery 的服务,又不能在上下文中起效。
大家是怎么解决相互 import 的问题的?
Python中使用Flask工厂模式创建app并配置Celery,如何解决循环import问题?
这个问题很典型,处理Flask工厂模式与Celery结合时的循环导入,核心思路是延迟初始化和明确依赖关系。
关键点在于:不要在模块顶层创建Celery实例,而是在工厂函数内部创建并配置它。这样就能确保Flask应用对象已经存在,从而打破循环。
下面是一个清晰、可运行的项目结构示例:
项目结构:
your_project/
├── app/
│ ├── __init__.py # Flask应用工厂
│ ├── celery_utils.py # Celery实例定义
│ ├── tasks.py # 你的Celery任务
│ └── routes.py # Flask路由
├── config.py # 配置文件
└── run.py # 应用启动入口
1. 配置文件 (config.py):
class Config:
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
2. Celery工具模块 (app/celery_utils.py):
这里只定义Celery类,但不传入Flask应用。
from celery import Celery
# 先创建一个“空”的Celery实例,不绑定任何Flask应用
celery = Celery()
3. Flask应用工厂 (app/__init__.py):
这是解决问题的核心。在工厂函数内部完成Celery的配置。
from flask import Flask
from .celery_utils import celery
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# 配置Celery
celery.conf.update(app.config)
# 可选:自动发现任务
celery.autodiscover_tasks(['app.tasks'])
# 注册蓝图等
from . import routes
app.register_blueprint(routes.bp)
return app
4. 任务定义 (app/tasks.py):
from .celery_utils import celery
@celery.task
def add_together(x, y):
return x + y
5. 路由示例 (app/routes.py):
from flask import Blueprint, jsonify
from .tasks import add_together
bp = Blueprint('main', __name__)
@bp.route('/add/<int:a>/<int:b>')
def trigger_task(a, b):
# 异步调用任务
task = add_together.delay(a, b)
return jsonify({'task_id': task.id}), 202
6. 应用启动入口 (run.py):
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run()
如何运行Celery Worker: 在项目根目录下,使用你工厂函数创建的应用上下文来启动worker:
celery -A app.celery_utils.celery worker --loglevel=info
或者,如果你的任务模块路径不同,确保-A参数指向包含celery实例的模块(这里是app.celery_utils)。
总结一下: 把Celery实例的创建和配置分两步走,在工厂里绑定Flask配置就搞定了。
不是有 init_app 方法嘛

