Django Vi中的Python异步

2024-09-27 07:28:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我想同时从Django视图上的API发出两个POST请求。

这就是我在django之外的工作方式。

import asyncio
import speech_recognition as sr

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.get_even_loop()
loop.run_until_complete(main("en-US", "es-ES"))

我对事件循环感到困惑。我怎么能在Django的视野里做到这一点?我需要为此使用嵌套函数吗?

def ibmaudio_ibm(request, language1, language2):
     #Asyncio code here

编辑:这是怎么回事?并行调用和crontab的调度是完全不同的。。。


Tags: djangorunimportloopasynciogetmaindef
3条回答

解决方法是将函数嵌套到另一个函数中。

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)

Django是一个同步框架,因此您不能在视图中使用任何async/await,因为没有循环或类似的东西。

您确实可以使用Django channels library来实现它,但是它会使您的视图本身处于异步状态,您不需要使用async另外,只需像以前那样连接通道并继续编码,而不需要任何异步功能。

在这种特殊情况下,您可以简单地使用ThreadPoolExecutor,asyncio在.run_in_executor中的hood下使用它(但在您的示例中还添加了多余的代码行/循环创建等)。

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.

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

相关问题 更多 >

    热门问题