Python Asyncio in Django View

前端 未结 4 1410
清歌不尽
清歌不尽 2020-12-13 20:52

I would like to make two POST requests from an API on a Django view at the same time.

This is how I would do it outside of django.

import asyncio
imp         


        
相关标签:
4条回答
  • 2020-12-13 21:12

    In this particular case you can simply use the ThreadPoolExecutor, asyncio is using it under the hood in .run_in_executor anyway (but also adds redundant lines of code / loop creation etc in your example).

    from concurrent.futures import ThreadPoolExecutor, wait
    
    # create the executor outisde of the view with the number of workers you may need
    executor = ThreadPoolExecutor(max_workers=2)
    
    def reco_ibm(lang):
        return(r.recognize_ibm(audio, key, secret language=str(lang), show_all=True))
    
    def djangoview(request, language1, language2):
        r = sr.Recognizer()
        with sr.AudioFile(path.join(os.getcwd(), "audio.wav")) as source:
            audio = r.record(source)
    
            # then use it pretty trivially:
            futures = []
            for lang in [language1, language2]:
                futures.append(executor.submit(reco_ibm, lang)
            completed, pending = wait(futures)
            # `pending` will always be empty here (see the docs on wait)
    
            result1, result2 = [i.resut() for i in completed]
    
        # do whatever you want with results etc.
    

    see https://docs.python.org/3/library/concurrent.futures.html

    0 讨论(0)
  • 2020-12-13 21:12

    You can try my way:

    1. At first you need to create app.py in your app_name folder
    2. Then fill your code:

      async def main(language1, language2): 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) 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

    3. in app_name folder fill your views.py:

      import asyncio from django.http import HttpResponse from . import app

      # Create your views here. def index(request): loop = asyncio.new_event_loop() ss = loop.run_until_complete(app.main(language1, language2)) loop.close() return HttpResponse(ss, content_type='text\plain')

    0 讨论(0)
  • 2020-12-13 21:25

    Django is a synchronous framework so you can't use any async/await in the views because of there no loop or something like that.

    You really can use Django channels library for it, but it will make your views asynchronous under the hood by itself, you don't need to use async also, just connect the channels a go on coding as you do it before, without any async features.

    0 讨论(0)
  • 2020-12-13 21:31

    Solution was to nest the function inside another one.

    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)
    
    0 讨论(0)
提交回复
热议问题