The method of using asyncio in View of Django
- 2021-07-16 02:45:24
- OfStack
Start
Django is a synchronous framework, and this article does not make Django an asynchronous framework. But for scenarios where http and api need to be requested multiple times in one view.
1 Simple example
Examples are from https://stackoverflow.com/questions/44667242/python-asyncio-in-django-view:
def djangoview(request, language1, language2):
async def main(language1, language2):
loop = asyncio.get_event_loop()
r = sr.Recognizer()
with sr.AudioFile(path.join(os.getcwd(), "audio.wav")) as source:
audio = r.record(source)
def reco_ibm(lang):
return(r.recognize_ibm(audio, key, secret language=lang, show_all=True))
future1 = loop.run_in_executor(None, reco_ibm, str(language1))
future2 = loop.run_in_executor(None, reco_ibm, str(language2))
response1 = await future1
response2 = await future2
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop = asyncio.get_event_loop()
loop.run_until_complete(main(language1, language2))
loop.close()
return(HttpResponse)
In this example, put both tasks into loop of asyncio and wait until both tasks are complete before returning to HttpResponse.
Using asyncio in View of Django
Now we can make an extension to the above example, so that it can be used more reasonably.
With asyncio, we usually create child threads to handle asynchronous tasks.
Create a single thread in wsgi. py and run the event loop:
import asyncio
import threading
...
application = get_wsgi_application()
# Create child threads and wait
thread_loop = asyncio.new_event_loop()
def start_loop(loop):
asyncio.set_event_loop(loop)
loop.run_forever()
t = threading.Thread(target=start_loop, args=(thread_loop,), daemon=True)
t.start()
Then you dynamically add tasks to view:
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
text = await response.text()
return text
def hello(request):
from yeezy_bot.wsgi import thread_loop
fut1 = asyncio.run_coroutine_threadsafe(fetch(url1), thread_loop)
fut2 = asyncio.run_coroutine_threadsafe(fetch(url2), thread_loop)
ret1 = fut1.result()
ret2 = fut2.result()
return HttpResponse('')
asyncio. run_coroutine_threadsafe () returns an Future object, so you can get the running result of the task through fut. result (). This method can also handle the sequence of data dependencies in API requests.