烧瓶投掷 'Working outside of request context.'

Flask throwing 'Working outside of request context.'

我正在尝试将 celery 用于我在 flask 中制作的应用程序,但出现以下错误 "Working outside of request context"。听起来我试图在前端发出请求之前访问请求对象,但我无法弄清楚出了什么问题。如果您能告诉我问题出在哪里,我将不胜感激。

[2017-04-26 13:33:04,940: INFO/MainProcess] Received task: app.result[139a2679-e9df-49b9-ab42-1f53a09c01fd]  
[2017-04-26 13:33:06,168: ERROR/PoolWorker-2] Task app.result[139a2679-e9df-49b9-ab42-1f53a09c01fd] raised unexpected: RuntimeError('Working outside of request context.\n\nThis typically means that you attempted to use functionality that needed\nan active HTTP request.  Consult the documentation on testing for\ninformation about how to avoid this problem.',)
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/celery/app/trace.py", line 367, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/Users/Pooneh/projects/applications/ray_tracer_app_flask/flask_celery.py", line 14, in __call__
    return TaskBase.__call__(self, *args, **kwargs)
  File "/Library/Python/2.7/site-packages/celery/app/trace.py", line 622, in __protected_call__
    return self.run(*args, **kwargs)
  File "/Users/Pooneh/projects/applications/ray_tracer_app_flask/app.py", line 33, in final_result
    light_position = request.args.get("light_position", "(0, 0, 0)", type=str)
  File "/Library/Python/2.7/site-packages/werkzeug/local.py", line 343, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/Library/Python/2.7/site-packages/werkzeug/local.py", line 302, in _get_current_object
    return self.__local()
  File "/Library/Python/2.7/site-packages/flask/globals.py", line 37, in _lookup_req_object
    raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.

This typically means that you attempted to use functionality that needed
an active HTTP request.  Consult the documentation on testing for
information about how to avoid this problem.

app.py

app = Flask(__name__)
app.config.update(CELERY_BROKER_URL = 'amqp://localhost//',
CELERY_RESULT_BACKEND='amqp://localhost//')

celery = make_celery(app)


@app.route('/')
def my_form():
    return render_template("form.html")

@app.route('/result')
def result():
    final_result.delay()
    return "celery!"

@celery.task(name='app.result')
def final_result():
    light_position = request.args.get("light_position", "(0, 0, 0)", type=str)
    light_position_coor = re.findall("[-+]?\d*\.\d+|[-+]?\d+", light_position)
    x = float(light_position_coor[0])
    y = float(light_position_coor[1])
    z = float(light_position_coor[2])

    encoded = base64.b64encode(open("/Users/payande/projects/applications/app_flask/static/pic.png", "rb").read())
    return jsonify(data=encoded)

Celery 任务 运行 由后台工作人员在 HTTP 请求之外异步执行(这是使用它们的主要好处之一),因此您无法访问任务中的 request 对象.

您可以将数据作为参数传递给任务:

final_result.delay(request.args.get("light_position"))

@celery.task(name='app.result')
def final_result(light_position):
    ...

当然这也意味着任务的 return 值不能用于 HTTP 响应(因为任务可以在响应发送后完成)。