【问题标题】:Flask throwing 'Working outside of request context.'烧瓶抛出“在请求上下文之外工作。”
【发布时间】:2017-04-26 21:00:15
【问题描述】:

我正在尝试将 celery 用于我在烧瓶中制作的应用程序,但我收到以下错误“在请求上下文之外工作”。听起来我正试图在前端发出请求之前访问请求对象,但我不知道出了什么问题。如果您能告诉我是什么问题,我将不胜感激。

[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)

【问题讨论】:

    标签: flask celery


    【解决方案1】:

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

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

    final_result.delay(request.args.get("light_position"))
    
    @celery.task(name='app.result')
    def final_result(light_position):
        ...
    

    当然这也意味着不能在HTTP响应中使用任务的返回值(因为在响应已经发送之后任务才能完成)。

    【讨论】:

    • 如果他想同时调用同步和异步模式会发生什么?像这样:@app.route('/result')def result():final_result()return "this is a sync request"@app.route('/result')def result():final_result()return "this is an async request"@celery.task(name='app.result')def final_result():light_position = request.args.get("light_position", "(0, 0, 0)", type=str) 。 ...return 'done'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 2012-10-29
    相关资源
    最近更新 更多