Передайте контекст приложения сельдерею в фреймворке. - PullRequest
0 голосов
/ 04 июля 2019

Я пытался добавить сельдерей в свой существующий проект колбы. После добавления во время работы я получил ошибку «работа вне контекста приложения». Кажется, что у сельдерея нет контекста моего приложения Но я не уверен, где в данном случае передать контекст приложения работнику сельдерея.

Вот моя текущая структура (я пытался следовать заводскому шаблону с чертежами и документами API):

-run.py
-app
    -module1
      -controller.py
      -model.py
      -service.py
    -__init__.py
    -config.py

Для init.py

# __init__.py
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from app.config import Config
from flask_restplus import Api
from celery import Celery

cors = CORS()
db = SQLAlchemy()
api = Api()
celery = Celery(__name__, broker=Config.CELERY_BROKER_URL, include=["app.module1.service"])

def create_app(config_class = Config):
    app = Flask(__name__, static_url_path='')
    app.config.from_object(Config)

    cors.init_app(app)
    db.init_app(app)
    api.init_app(app=app)
    celery.conf.update(app.config)

    from app.module1.controller import blueprint
    from app.module1.controller import ns

    app.register_blueprint(blueprint)
    api.add_namespace(ns)

    return app

Для run.py

from app import create_app
app = create_app()
if __name__ == '__main__':
    app.run(threaded=True, debug=True)

Для service.py

from app import db, celery
@celery.task(bind=True)
def service1(self):
    # do somethigng & return

Для controller.py

from flask import Blueprint
from flask_restplus import Api, Resouce
blueprint = Blueprint('service', __name__)
apis = Api(app = blueprint)
ns = apis.namespace('service', 'service description')
@ns.route("/")
class SomeList(Resource):
    def get(self):
        service1.apply_async()
        # return

1 Ответ

1 голос
/ 04 июля 2019

Я думаю, что путаница основана на том факте, что вы пытаетесь «передать» контекст приложения работнику Celery.В действительности, процесс Flask не может передать контекст работнику, потому что это разные процессы.Рабочий процесс Celery должен создать свой собственный экземпляр приложения Flask, вызвав create_app(), чтобы при необходимости он мог выдвигать свои собственные контексты приложения.

Например, в вашей задаче service1:

from app import db, celery, create_app

@celery.task(bind=True)
def service1(self):
    app = create_app()
    with app.app_context():
        # do somethigng & return

Чтобы сделать это немного более эффективным, вы можете создать единый глобальный app, который будет использоваться всеми вашими задачами:

from app import db, celery, create_app
app = create_app()

@celery.task(bind=True)
def service1(self):
    with app.app_context():
        # do somethigng & return
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...