依赖安装
Fastapi 有版本要求,需要的 Python
版本至少是 Python 3.8(不要犟,按照版本要求来,我最先也是在我 Python3.6 上装的,果不其然跑不起来),幸好我 Win7 老古董能支持的 Python 最高版本可以到 3.8 ,这也算我最后的倔强了。据说这个框架有和
Go 并肩的极高性能,我倒是想特别见识一下。
大家也可以直接去看用户指南 教程 - 用户指南 - FastAPI ,这里面讲解得更加详细。
安装 fastapi
这个用 pip 安装就是了,没啥多说的,特别是安装有多个 python 解释器的时候,要关注下 pip 和 python 解释器的对应关系。当然,用虚拟环境也是不错的选择。
pip3.8 install fastapi
安装ASGI 服务器
pip3.8 install "uvicorn[standard]"
这点和 flask 不太一样,flask 创建的 app 直接用 app.run() 就跑起来了,它好像不能这么做,需要使用安装的 uvicorn 去启动服务。
Uvicorn
是一个基于ASGI(Asynchronous Server Gateway Interface)
的异步Web
服务器,用于运行异步Python web
应用程序。它是由编写FastAPI
框架的开发者设计的,旨在提供高性能和低延迟的Web
服务。
快速启动
hello world
import uvicorn
from fastapi import FastAPIapp = FastAPI()@app.get("/")
async def index():"""注册一个根路径:return:"""return {"message": "Hello World"}if __name__ == "__main__":uvicorn.run(app)
文档访问
SwaggerUi风格文档:
http://127.0.0.1:8000/docs
有了路由的在线文档,对于接口对接或者 API 接口文档编写的时候,就真正方便多了。
OpenAPI
FastAPI
框架内部实现了OpenAPI
规范,通过访问 http://127.0.0.1:8000/openapi.json,我们可以看到整个项目的 API
对应的JSON
描述。简单来说,这就是一个结构化的 Swagger 文档,返回的细节很详细。
{"openapi": "3.1.0","info": {"title": "FastAPI","version": "0.1.0"},"paths": {"/": {"get": {"summary": "Index","description": "注册一个根路径\n:return:","operationId": "index__get","responses": {"200": {"description": "Successful Response","content": {"application/json": {"schema": {}}}}}}}}
}
路径
路径参数
类似于 Flask 的动态路由,使用 Python 标准类型注解(自从有了类型注解以后,总感觉 Python 变了,不像是原来那个不关心类型的脚步语言了),声明路径操作函数中路径参数的类型。
import uvicorn
from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id}")
def read_item(item_id: int):return {"item_id": item_id}if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)
如果输入的参数类型不匹配的话,还会报错。
{"detail": [{"type": "int_parsing","loc": ["path","item_id"],"msg": "Input should be a valid integer, unable to parse string as an integer","input": "xyz","url": "https://errors.pydantic.dev/2.6/v/int_parsing"}]
}
路径顺序
import uvicorn
from fastapi import FastAPIapp = FastAPI()@app.get("/users/me")
async def read_user_me():return {"user_id": "the current user"}@app.get("/users/{user_id}")
async def read_user(user_id: str):return {"user_id": user_id}if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)
比如要使用 /users/me
获取当前用户的数据。然后还要使用 /users/{user_id}
,通过用户 ID 获取指定用户的数据。由于路径操作是按顺序依次运行的,因此,一定要在 /users/{user_id}
之前声明 /users/me
。这个其实好理解,相当于先写的动态路由把后面的其他路由通配了。一般如果代码审查比较严格的话,是不允许出现这种情况的。特殊的路由就用特殊的路径,尽量不要和通配路径去碰瓷。
路径预设值
路径操作使用 Python 的 Enum
类型接收预设的路径参数。也就是说和动态路由类似,但是动态值的可选范文是提前限定好的。
import uvicorn
from enum import Enumfrom fastapi import FastAPIclass ModelName(Enum):alexnet = "alexnet"resnet = "resnet"lenet = "lenet"app = FastAPI()@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):if model_name is ModelName.alexnet:return {"model_name": model_name, "message": "Deep Learning FTW!"}if model_name.value == "lenet":return {"model_name": model_name, "message": "LeCNN all the images"}return {"model_name": model_name, "message": "Have some residuals"}if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)
查询参数
查询参数都是 URL 的组成部分,因此,它们的类型本应是字符串。但声明 Python 类型之后,这些值就会转换为声明的类型,并进行类型校验。
import uvicorn
from fastapi import FastAPIapp = FastAPI()fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):return fake_items_db[skip: skip + limit]if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)
默认值
即在声明类型的时候,按照上面的示例指定默认值即可。
可选参数
将参数的默认值设置为 None 之后,就可以将参数变为可选参数。
import uvicorn
from fastapi import FastAPIapp = FastAPI()fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]@app.get("/items/{item_id}")
async def read_item(item_id: str, query: str = None):if query:return {"item_id": item_id, "query": query}return {"item_id": item_id}if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)
内容估计有些多,先写一部分,后面再补充。
To be continued