【问题标题】:How to enable uvicorn to run asynchronously constructed app?如何让 uvicorn 运行异步构建的应用程序?
【发布时间】:2021-04-26 11:53:54
【问题描述】:

给定main.py

import asyncio

async def new_app():
    # Await some things.

    async def app(scope, receive, send):
        ...

    return app

app = asyncio.run(new_app())

接着是:

uvicorn main.app

给予:

RuntimeError: asyncio.run() cannot be called from a running event loop

这是因为uvicorn 在导入我的应用程序之前已经启动了一个事件循环。 uvicorn下如何异步构造应用?

【问题讨论】:

    标签: python async-await python-asyncio uvicorn asgi


    【解决方案1】:

    你不需要使用asyncio.run。你的类或函数应该只实现ASGI 接口。像这样,最简单可行:

    # main.py
    def app(scope):
        async def asgi(receive, send):
            await send(
                {
                    "type": "http.response.start",
                    "status": 200,
                    "headers": [[b"content-type", b"text/plain"]],
                }
            )
            await send({"type": "http.response.body", "body": b"Hello, world!"})
    
        return asgi
    

    你可以在uvicorn下启动它:uvicorn main:app

    参数main:app将被uvicornexecuted在其事件循环中以这种方式解析导入:

     app = self.config.loaded_app
     scope: LifespanScope = {
         "type": "lifespan",
         "asgi": {"version": self.config.asgi_version, "spec_version": "2.0"},
     }
     await app(scope, self.receive, self.send)
    

    如果你想制作一个可执行的模块,你可以这样做:

    import uvicorn
    # app definition
    if __name__ == "__main__":
        uvicorn.run(app, host="0.0.0.0", port=8000)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-15
      • 2016-01-04
      • 1970-01-01
      • 1970-01-01
      • 2019-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多