Python 如何使uvicorn运行异步构造的应用程序?

Python 如何使uvicorn运行异步构造的应用程序?,python,async-await,python-asyncio,uvicorn,asgi,Python,Async Await,Python Asyncio,Uvicorn,Asgi,给定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

给定
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
下异步构造应用程序?

您无需使用
asyncio.run
。您的类或函数应该只实现接口。像这样,最简单的方法是可行的:

# 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
将由
uvicorn
解析导入,并在其eventloop中以这种方式导入:

 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)