Reputation: 1194
I have an async get_forecastweather function which gives me JSON weather data, I understand that we can't execute the async function inside sync, but how do i do it inside a separate thread, need help, thanks in advance
def weather_detail(request):
if request.method == 'GET':
city_name = 'my_city'
key = 'mykey'
result = None
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
response = executor.submit(get_forecastweather,city_name,key)
result = response.result()
print('Result from thread ',result)
return render(request,'weather/weather_detail.html')
the error I am getting is
RuntimeWarning: coroutine 'get_forecastweather' was never awaited
response = wrapped_callback(request, *callback_args, **callback_kwargs)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Upvotes: 3
Views: 6985
Reputation: 10926
You can write a small wrapper function that runs your async routine in a separate thread and returns the result. You can simply use asyncio.run
for this. The ThreadPoolExecutor mechanism will create the new threads for you, and the asyncio.run
method will create a new event loop, run it, return the result and then close the loop. Here is an example program, where instead of your request for the weather I generate a random integer between two limits:
from concurrent.futures import ThreadPoolExecutor
import random
import time
import asyncio
# You would use weather_detail here
async def get_random(n0, n1):
await asyncio.sleep(3.0)
return random.randint(n0, n1)
def wrapper(coro):
return asyncio.run(coro)
def main():
print("Start", time.ctime())
with ThreadPoolExecutor(max_workers=3) as executor:
arglist = ((10, 20), (30, 40), (50, 60), (90, 100))
coros = [get_random(n0, n1) for n0, n1 in arglist]
for r in executor.map(wrapper, coros):
print(r, time.ctime())
main()
# Output:
# Start Fri Sep 10 00:45:13 2021
# 15 Fri Sep 10 00:45:16 2021
# 40 Fri Sep 10 00:45:16 2021
# 52 Fri Sep 10 00:45:16 2021
# 99 Fri Sep 10 00:45:19 2021
I included time stamps to show the time delays, and prove that three threads are running in parallel. The first three calls to wrapper finish in 3 seconds but the fourth takes 3 more, since there are only three worker threads.
Upvotes: 7