使用异步服务器Uvicorn启动fastapi

在了解使用异步服务器Uvicorn启动fastapi之前,我们先看一下下面的一些知识点。

ASGI

在 Python3.5 之后增加 async/await特性之后,异步编程变得异常火爆,越来越多开发者投入异步的怀抱。直到最近,Python 仍缺乏用于asyncio框架的最低限度的低级服务器/应用程序接口。而 ASGI 协议规范的出现填补了这一空白,这意味着我们现在能够开始构建可在所有异步框架中使用的通用工具集。ASGI 帮助 Python 在 Web 框架上和Node.JSGolang相竟争,目标是获得高性能的 IO 密集型任务,ASGI 作为异步网关协议接口,一个介于网络协议服务和 Python 应用之间的标准接口,能够处理多种通用的协议类型,包括HTTPHTTP2WebSocket

ASGI(异步服务器网关接口)是WSGI的精神继承者,旨在在具有异步功能的Python Web服务器,框架和应用程序之间提供标准接口。

Uvicorn

Uvicorn 是一个快速的 ASGI 服务器,Uvicorn 是基于uvloophttptools构建的,是 Python 异步生态中重要的一员。

Uvicorn当前支持 HTTP / 1.1WebSockets,将来计划支持HTTP / 2

什么是 uvloop 和 httptools ?

uvloop用于替换标准库asyncio 中的事件循环,使用Cython实现,它非常快,可以使asyncio的速度提高 2-4 倍。

httptoolsnodejs HTTP 解析器 的 Python 实现。

Uvicorn使用方法

1
pip install uvicorn

创建一个文件 example.py

1
2
3
4
5
6
7
8
9
10
11
12
13
async def app(scope, receive, send):
assert scope['type'] == 'http'
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!',
})

启动Uvicorn

1
uvicorn example:app

也可以直接允许脚本

1
2
3
4
5
6
7
import uvicorn

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

if __name__ == "__main__":
uvicorn.run("example:app", host="127.0.0.1", port=8000, log_level="info")

使用uvicorn启动fastapi

我们直接看下代码

1
2
3
4
5
6
7
8
9
10
11
import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
return {"message": "Hello World"}

if __name__ == '__main__':
uvicorn.run(app=app)

我们看下run方法的源码

yJU1oT.png

我们看到You must pass the application as an import string to enable 'reload' 即如果我们想配置自动重新加载 需要将app对象设置成字符串。

除此之外,我们还要看看should_reload是什么:

1
2
3
@property
def should_reload(self):
return isinstance(self.app, str) and (self.debug or self.reload)

不仅要设置app为字符串,还要设置debug或者reload为True才能自动重新加载

因此最终的启动为:

1
uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!