我将以我知道这个问题有一些解决方案为序,尽管它们都没有遵循本指南,似乎没有回答我的问题。
我从我在Flask的Celery应用程序收到这个错误。
[2021-11-23 22:50:01,469: ERROR/ForkPoolWorker-1] Task smartful_versioning_flask.test_celery_task[6dda4a4b-cf64-4fdc-8317-237dca9ad31b] raised unexpected: RuntimeError('Working outside of application context.nnThis typically means that you attempted to use functionality that needednto interface with the current application object in some way. To solventhis, set up an application context with app.app_context(). See thendocumentation for more information.')
Traceback (most recent call last):
File "/var/smartful_flask/smartful_venv/lib/python3.7/site-packages/celery/app/trace.py", line 450, in trace_task
R = retval = fun(*args, **kwargs)
File "/var/smartful_flask/smartful_venv/lib/python3.7/site-packages/celery/app/trace.py", line 731, in __protected_call__
return self.run(*args, **kwargs)
File "/var/smartful_flask/smartful_versioning_flask.py", line 21, in test_celery_task
return jsonify({"something": "something"})
File "/var/smartful_flask/smartful_venv/lib/python3.7/site-packages/flask/json/__init__.py", line 336, in jsonify
if current_app.config["JSONIFY_PRETTYPRINT_REGULAR"] or current_app.debug:
File "/var/smartful_flask/smartful_venv/lib/python3.7/site-packages/werkzeug/local.py", line 422, in __get__
obj = instance._get_current_object()
File "/var/smartful_flask/smartful_venv/lib/python3.7/site-packages/werkzeug/local.py", line 544, in _get_current_object
return self.__local() # type: ignore
File "/var/smartful_flask/smartful_venv/lib/python3.7/site-packages/flask/globals.py", line 47, in _find_app
raise RuntimeError(_app_ctx_err_msg)
**RuntimeError: Working outside of application context.**
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
经过多次故障排除,我完全不知所措。异常中引用的应用程序上下文在哪里传递?
from flask import Flask, jsonify
from celery import Celery
app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
@celery.task
def test_celery_task():
return jsonify({"something": "something"})
@app.route("/web/start/backend", methods=['POST'])
def start_task():
task = test_celery_task.apply_async()
return task.id
@app.route("/web/check-status/backend/<task_id>", methods=['GET'])
def check_task(task_id):
task = test_celery_task.AsyncResult(task_id)
if task.state == 'PENDING':
return jsonify({
"task": task_id,
"state": task.state,
"data": None,
"complete": False,
"error": False
})
elif task.state == 'SUCCESS':
print(task.info)
else:
print(task.state)
return "task.info"
if __name__ == "__main__":
app.run()
正如预期的那样,通过这种回溯,任务将失败,并且永远不会从后端返回。我正在使用Ngnix、wsgi、Supervisor来提供服务——尽管无论是否有Supervisor生成工人,都存在相同的问题。
我确信我忽略了一些愚蠢和琐碎的事情,尽管和往常一样——太盲目了,看不见
我在这里找到了修复方法,并为其他有类似情况的人做了标记。这与主管正在使用的工作目录有关。
我进入我的flask应用程序的目录,手动生成了一个工人:
# smartful_venv/bin/celery --app=smartful_versioning_flask.celery worker --loglevel=DEBUG
我运行了我的烧瓶应用程序,如问题所示,我的退货打印成功。我的情况可能是主管无法访问我正在使用的工作目录。它没有明确说明,但在主管文档中并没有真正讨论这个问题,尽管主管报告它是以root身份运行的——这是谎言!
编辑以添加:
在另一个任务中,我需要在做任何事情之前添加with app.app_context():
。这对我来说很奇怪,但它有效。如果有人能解释为什么应用程序上下文只存在于with之后,这可能会引发一场健康的讨论。