FastAPI备忘录
基本使用备忘录
交互式API文档
我们访问以下两个地址,可获取自动生成的交互式API文档,并且当代码改动时文档会自动更新。方便我们的开发调试。
- http://127.0.0.1:8000/docs (基于 Swagger UI)
- http://127.0.0.1:8000/redoc (基于 ReDoc)
Pydantic: 类型强制检查
对于 API 服务,支持类型检查非常有用,会让服务更加健壮,也会加快开发速度,因为开发者再也不用自己写一行一行的做类型检查。
路径参数
路径参数的预定义值
我们可以使用Python Enum来声明路径参数的预定义值。
from enum import Enum
class ModelName(str, Enum):
alexnet = "alexnet"
resnet = "resnet"
lenet = "lenet"
这里,我们声明了一个类ModelName,它继承自str(这样限制了值的类型必须是字符串类型)和Enum。
路径参数中包含文件路径
当路径参数中包含文件路径时,比如 /files/{file_path}
,我们可以用声明file_path类型的方式进行支持。
这里 :path
指出了file_path可以匹配任何文件路径。
from fastapi import FastAPI
app = FastAPI()
@app.get("/files/{file_path:path}")
async def read_file(file_path: str):
return {"file_path": file_path}
请求参数
FastAPI可以非常智能的识别参数种类,这里参数item_id是一个路径参数,而参数q是一个请求参数。
你可以同时声明多个路径参数、多个请求参数,并且不用考虑声明顺序。FastAPI可以准确无误的识别参数类型。
Request Body
多个Request Body
嵌入单个Request Body
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item = Body(..., embed=True)):
results = {"item_id": item_id, "item": item}
return results
对于Request Body里的单个数值,FastAPI提供了便利的操作方法Body。注意,这里如果没有Body方法的话,参数importance就只是个请求参数,所以务必注意下。
基于Query的请求参数附加信息
q: str = Query(None) # 可选参数声明,等同于 q: str = None
q: str = Query("query") # 缺省值参数声明,等同于 q: str = "query"
q: str = Query(...) # 必选参数声明,等同于 q: str
q: str = Query(None, max_length=50) # 限制q的最大长度不超过50
数值型参数信息说明:
gt: 大于(greater than)
ge: 大于或等于(greater than or equal)
lt: 小于(less than)
le: 小于或等于( less than or equal)
主要用于字符串参数的附加信息:
min_length:最小长度
max_length:最大长度
regex:正则表达式
主要用于自动化文档的附加信息:
title:参数标题
description:参数描述信息
deprecated:表示参数即将过期
特殊附加信息:
alias:参数别名
基于Query的请求参数列表
@app.get("/items/")
async def read_items(q: List[str] = Query(["foo", "bar"])):
query_items = {"q": q}
return query_items
基于fastapi.Path的路径参数附加信息
注意,路径参数在URL里是必选的,因此Path的第一个参数是 ...
,即使你传递了None或其他缺省值,也不会影响参数的必选性。
@app.get("/items/{item_id}")
async def read_items(
q: str,
item_id: int = Path(..., title="The ID of the item to get")
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
参数顺序
不带缺省值的参数应放在前面,而FastAPI根据参数名称、类型以及声明方法(如Query、Path等等)来识别具体参数意义,并不关心参数顺序。但这样对开发人员来说容易把多种类型参数混淆,怎么办?
@app.get("/items/{item_id}")
async def read_items(
*, item_id: int = Path(..., title="The ID of the item to get"), q: str
):
参数排序的技巧:通过传递 *
作为第一个参数,就解决了上面的参数顺序问题:Python并不会对 *
做任何操作。但通过识别 *
,Python知道后面所有的参数都是关键字参数(键值对),通常也叫kwargs,无论参数是否有默认值。
Pydantic复杂模型
Pydantic模型的附加信息
Pydantic嵌套模型
复杂数据类型
Cookie操作
基于Query、Path等模块同样的模式,我们可以利用 Cookie
模块来声明cookies。Cookie是Query、Path的姐妹类,它们都继承自Param类。
from fastapi.responses import JSONResponse
@app.post("/cookie/")
def create_cookie():
content = {"message": "Come to the dark side, we have cookies"}
response = JSONResponse(content=content)
response.set_cookie(key="fakesession", value="fake-cookie-session-value")
return response
Header操作
Header
是Query、Path、Cookie的姐妹类,它们都继承自Param类。
读取Header信息
@app.get("/items/")
async def read_items(*, user_agent: str = Header(None)):
return {"User-Agent": user_agent}
自动转换
大多数headers中都带有"-“字符,如"User-Agent”,但在Python中,User-Agent
并不是一个合法的变量名称。
我们可以通过设置Header中的 convert_underscores
参数为Flase,来禁止这种从 _
到 -
的字符转换(大多数情况下并并不需要)。
返回Header信息
使用Response参数
我们可以在路径操作函数中声明Response参数,然后给这个临时的Response对象设置header信息。
FastAPI通过这个临时的Response对象解析出header信息(以及cookie信息和状态码等),然后放入到最终返回的Response对象中。
我们也可以在依赖项中使用Response参数,然后设置header信息(以及cookie信息等)。
@app.get("/headers-and-object/")
def get_headers(response: Response):
response.headers["X-Cat-Dog"] = "alone in the world"
return {"message": "Hello World"}
直接返回Response
我们也可以在直接返回的Response对象中设置header信息。
@app.get("/headers/")
def get_headers():
content = {"message": "Hello World"}
headers = {"X-Cat-Dog": "alone in the world", "Content-Language": "en-US"}
return JSONResponse(content=content, headers=headers)
Response模型
在路径操作中,我们可以用参数response_model来声明Response模型。常常用于:限制输出数据只能是所声明的Response模型。
Response自定义状态码
@app.put("/get-or-create-task/{task_id}", status_code=200)
def get_or_create_task(task_id: str, response: Response):
if task_id not in tasks:
tasks[task_id] = "This didn't exist before"
response.status_code = status.HTTP_201_CREATED
return tasks[task_id]
Form表单数据
安装组件 pip install python-multipart
from fastapi import Form
Form的详细使用可参考Query、Path、Cookie、Body。它直接继承自Body。
@app.post("/login/")
async def login(*, username: str = Form(...), password: str = Form(...)):
return {"username": username}
- 点赞
- 收藏
- 关注作者
评论(0)