Flocks throwing "runs out of request context" when starting a subflow

I am trying to start a new thread in Python inside a Flask application. I am doing background work triggered by a request, but I do not need to wait for the work to complete to respond to the request.

Is it possible to ask a flask request in this threat for a request that came? The reason is that our ACL for our database queries (mongoengine before mongoDB) relies on the request user (he grabs it from the request object on the flask) to find out if they have access to the objects and its bloat because the request is not available in the subflow.

Any thoughts would be greatly appreciated.

Here's the pseudo-code of how I'm processing it now, but it doesn't work.

@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" 
+42
python flask mongoengine
Mar 29 '12 at 19:02
source share
4 answers

Wrap the stream code in test_request_context so that you have access to the context locales :

 @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" 

Edit : It is worth noting that the stream will have a different context than the original request. Before creating a stream, you need to extract any interesting request data, such as a user ID. You can then capture the (other) user object in the subflow using an identifier.

+57
Mar 29 '12 at 19:32
source share

Starting from version 0.10, there is a supported method: http://flask.pocoo.org/docs/api/#flask.copy_current_request_context

If you want the hosts before_request start, you must call current_app.preprocess_request() inside the decorated function.

+28
Jul 11 '13 at 13:25
source share

You can copy the necessary information and transfer it:

 @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" 
+5
May 08 '15 at 9:45
source share

As @runfalk pointed out, you will need to use @copy_current_request_context . Here is a snippet of working code:

 import threading from flask import request, jsonify, copy_current_request_context @app.route('/foo') def get_foo(): @copy_current_request_context def foo_main(): # insert your code here print(request.url) threading.Thread(target=foo_main).start() return jsonify({'status': 'started'}) 
0
Nov 30 '18 at 15:01
source share



All Articles