Reputation: 5352
I'm trying to make multiple requests async and get response back, I'm using concurrent.futures
to do this, but inside my function using current_app
which from flask
and I always got this error:
RuntimeError: Working outside of application context.
I don't know how to resolve this. Can anyone please help?
Below are my code:
run.py:
import concurrent.futures
from flask import current_app
from http_calls import get_price, get_items
def init():
with current_app._get_current_object().test_request_context():
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
futs = []
futs.append(executor.submit(get_price))
futs.append(executor.submit(get_items))
print([fut.result() for fut in concurrent.futures.as_completed(futs)])
init()
http_calls.py
from flask import current_app
def get_price():
url = current_app.config['get_price_url']
return requests.get(url).json()
def get_items():
url = current_app.config['get_items_url']
return requests.get(url).json()
Upvotes: 11
Views: 10588
Reputation: 19
def with_app_context(cls, app, func):
def wrapper(*args, **kwargs):
with app.app_context():
return func(*args, **kwargs)
return wrapper
you can use wrapper for achieving this. you can call your function from thread pool like below
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
# download using wkhtmltopdf (helps to address access denied issues)
res = executor.submit(with_app_context(app, cls.some_func))
Upvotes: 0
Reputation: 5167
I was running into similar issues around using concurrent.futures with Flask. I wrote Flask-Executor as a Flask-friendly wrapper for concurrent.futures to solve this problem. It may be an easier way for you to work with these two together.
Upvotes: 16
Reputation: 6475
You should import your Flask instance in your script. Use current_app
under the app context.
import concurrent.futures
from your_application import your_app # or create_app function to return a Flask instance
from flask import current_app
from http_calls import get_price, get_items
def init():
with your_app.app_context():
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
...
Upvotes: 3