当启动子线程时,引发瓶颈“在请求上下文之外工作”

我正在尝试在Flask应用程序中启动Python中的新线程。 我正在做后台工作,由请求触发,但我不需要等待工作来响应请求。

是否有可能在这个子威胁的烧瓶请求中设置请求? 原因是,我们对我们的DB(mongoDB前面的mongoengine)的查询的ACL依赖于请求的用户(它从瓶子的请求对象中抓取它)来查看它们是否有权访问这些对象,并且由于请求是在子线程中不可用。

任何想法将不胜感激。

这里是我如何处理它的伪代码,但它不工作。

@app.route('/my_endpoint', methods=['POST']) def my_endpoint_handler(): #do tracking in sub-thread so we don't hold up the page def handle_sub_view(req): from flask import request request = req # Do Expensive work thread.start_new_thread(handle_sub_view, (request)) return "Thanks" 

将你的线程代码test_request_contexttest_request_context这样你就可以访问上下文本地 :

 @app.route('/my_endpoint', methods=['POST']) def my_endpoint_handler(): #do tracking in sub-thread so we don't hold up the page def handle_sub_view(req): with app.test_request_context(): from flask import request request = req # Do Expensive work thread.start_new_thread(handle_sub_view, (request)) return "Thanks" 

编辑 :值得指出的是,线程将有一个不同于原始请求的上下文。 在产生线程之前,您需要提取任何有趣的请求数据,例如用户ID。 然后,您可以使用该ID在子线程中获取(不同的)用户对象。

从版本0.10开始,有一个支持的方法: http : //flask.pocoo.org/docs/api/#flask.copy_current_request_context

如果你想让before_request钩子运行,你必须在装饰函数内部调用current_app.preprocess_request()

你可以复制所需的信息并通过它

 @app.route('/my_endpoint', methods=['POST']) def my_endpoint_handler(): #do tracking in sub-thread so we don't hold up the page def handle_sub_view(data): # Use the data in subprocess data = request.get_json() # copy the data thread.start_new_thread(handle_sub_view, data) return "Thanks"