FastAPI 允许你为参数声明额外的信息和校验
对于路径参数,我们通常会对路径参数的类型进行校验,判断其是否符合要求。通常我们会这么做:
@app.get("/items/{item_id}")
async def item_details(item_id: uuid.UUID|int):
return {"item_id": item_id}
用于判断传递的参数是否为uuid.UUID
类型或者int
类型。当传递的item_id不是uuid.UUID
类型或者int
类型,将会引发422错误。错误信息如下:
{
"detail": [
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid uuid",
"type": "type_error.uuid"
},
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
这只是对参数的类型做一些校验,如果我们需要做一些复杂的校验,例如对参数的大小,长度做判断时,我们可以使用到Path
类型。使用如下:
from fastapi import Path
@app.get("/items/{item_id}")
async def item_details(item_id: int = Path(gt=0, lt=100)):
return {"item_id": item_id}
表示只接收大于0,且小于100的item_id参数。若不符合条件,同样也会引发422错误。Path
除了可以对参数做一些校验操作之外,它还可以在Swagger UI中,对该接口参数做一些说明,如下:
from fastapi import Path
@app.get("/items/{item_id}")
async def item_details(item_id: int = Path(title='标题', description='描述', example=2, deprecated=True)):
return {"item_id": item_id}
可以看到,title
参数并未起作用,但是description
属性生效了。
Path
常见参数如下:
default
: 默认值,任何类型。 当设置了该值,表明该参数非必须参数。因路径参数皆为必选参数,所以该参数不支持使用alias
: 别名, str
类型。Path
不支持title
: Swagger UI中参数的标题,str
类型。Path
/Query
操作不起作用description
: Swagger UI中参数的描述,str
类型gt
: 大于,数字类型ge
: 大于或等于,数字类型lt
: 小于,数字类型le
: 小于或等于,数字类型min_length
: 最小长度,int
类型max_length
: 最大长度,int
类型regex
: 正则匹配,str
类型example
: Swagger UI中参数的示例值,任何类型examples
: Swagger UI中参数的示例值,Dict类型。Path
/Query
操作不起作用deprecated
: 是否过期,bool
类型,默认Falseinclude_in_schema
: Swagger UI中是否添加对参数的说明,bool
类型,默认True查询参数的校验与路径参数基本一致,但是查询参数使用的是Query
。使用如下:
@app.get("/items")
async def item_list(item_id: int = Query(title='标题', description='描述', example=2, deprecated=True),
offset: int = Query(default=0, title='偏移量', description='偏移量', example=0),
limit: int = Query(default=10, title='数量', description='数量', example=10)):
return {"item_id": item_id, "offset": offset, "limit": limit}
在上面,我们可以看到,我们想将该参数设置为非必须
,我们只需要给default
设置一个值即可,设置为必须参数,则不使用该参数即可!如果我们想显示的声明该参数是必须的,我们可以使用default=...
来表示,如下:
@app.get("/items")
async def item_list(item_id: int = Query(default=...)):
pass
或者使用Required
类来表示,如下:
from pydantic import Required
@app.get("/items")
async def item_list(item_id: int = Query(default=Required)):
pass
我们还可以对Query Params
起一个别名,如此我们将用到alias
参数,该别名将用于在URL中查找查询参数值:
@app.get("/items")
async def item_list(q: str | None = Query(default=None, alias='item-query')):
return {"item": q}
如此,我们可以请求http://localhost:8000/items?item-query=1
来获取数据了,而http://localhost:8000/items?q=1
将会返回{"item": null}
Query
支持的其他参数与Path
基本相同!!
接收的不是JSON
,而是表单字段时,要使用到Form
。Form
参数的使用方式与Path
和Query
一样,使用如下:
from fastapi import Form
@router.post("/home")
async def home(name: str = Form(title='名称', description='详细描述', example='苹果'),
password: str = Form(title='名称', description='详细描述', example='苹果')):
return {'code': 1}
Form
支持的其他参数与Query
和Path
基本相同!
服务端介绍客户端上传的文件有两种方式:File
和UploadFile
。使用如下:
from fastapi import File, UploadFile
@router.post('/upload')
async def upload(f: bytes = File(title='文件', description='上传文件')):
return {"file_size": len(f)}
@router.post("/v2/upload")
async def v2_upload(f: UploadFile):
return {"filename": f.filename}
两种方式都是通过multipart/form-data
形式接收文件的!
UploadFile
与bytes
相比有更多优势:
spooled
文件:FastAPI
会把文件存入磁盘;file-like
async 接口;SpooledTemporaryFile
对象,可直接传递给其他预期file-like
对象的库UploadFile
具有如下属性:
filename
: 上传文件名字符串(str),例如,aaa.png
content_type
: 内容类型字符串,例如,image/png
file
: 一个SpooledTemporaryFile
(file-like
对象)对象UploadFile
支持以下async
方法:
write(data)
: 把data
(str
或bytes
)写入文件read(size)
: 按指定数量的字节或字符(size
(int
))读取文件内容seek(offset)
: 移动至文件offset
(int
)字节处的位置;close()
: 关闭文件在上一章已经讲到,要使用请求体参数,那么就需要使用到pydantic
。因此我们如果需要对请求体参数做校验的话,我们需要使用到Field
模块,且需要在pydantic
中使用,如下:
from pydantic import Field
from pydantic import BaseModel
class Item(BaseModel):
name: str = Field(title='名称', description='详细描述', example='苹果')
price: float = Field(title='价格', description='价格描述', example=20)
@app.post("/items/")
async def create_item(item: Item):
return {"name": item.name, "price": item.price}
除此之外,请求体参数也可以向查询参数一样,定义在方法的参数里面。此时,我们就需要使用到Body
模块,使用如下:
from fastapi import Body
@app.post("/items/")
async def create_item(name: str = Body(title='名称', description='详细描述', example='苹果'),
price: float = Body(title='价格', description='价格描述', example=20)):
return {"name": name, "price": price}
Body
支持的其他参数Query
与Path
基本相同,但是example
在Body
中不起作用
Field
常见参数如下:
default
: 默认值,任何类型。 当设置了该值,表明该参数非必须参数default_factory
: 生成的默认值的函数,接收一个Callable
类型。default
与default_factory
不可同时存在alias
: 别名, str
类型。Path
不支持title
: Swagger UI中参数的标题,str
类型。Path
/Query
操作不起作用description
: Swagger UI中参数的描述,str
类型exclude
: 是否排除该字段。当设置为True
时,BaseModel
调用dict
方法且传入默认参数时,将不会载入该字段include
: 是否包含该字段。当设置为True
时,BaseModel
调用dict
方法且传入默认参数时,将会载入该字段const
: bool
类型,当设置为True
时,那么该字段必须有default
值,如果传递了,值必须等于default
设置的值gt
: 大于,数字类型ge
: 大于或等于,数字类型lt
: 小于,数字类型le
: 小于或等于,数字类型multiple_of
: 接收一个数字类型,表示为几的倍数。例如multiple_of
的值为2,那么该字段的值必须是2的倍数allow_inf_nan
: bool
类型,表示是否允许字段为NaN或无穷大(+inf或-inf)。默认为True,为与JSON兼容请设置为False。max_digits
: int类型
,表示最大位数,字段类型须设置为decimal.Decimal
类型。长度计算中不包括小数点前的零或小数点后的零decimal_places
: int类型
,表小数最大位数,字段类型须设置为decimal.Decimal
类型。长度计算中不包括小数点前的零或小数点后的零min_items
: int
类型,表示列表的最小长度,字段类型须设置为list
类型max_items
: int
类型,表示列表的最大长度,字段类型须设置为list
类型unique_items
: bool
类型,字段类型须设置为list
类型。设置为True
时,表示列表中不可存在重复的值min_length
: 最小长度,int
类型max_length
: 最大长度,int
类型allow_mutation
: int
类型,表示是否强制类型匹配,默认为True
。当设置为True
时,当传递的参数不是指定类型的,那么将会引发TypeError
错误regex
: 正则匹配,str
类型example
: Swagger UI中参数的示例值,任何类型examples
: Swagger UI中参数的示例值,Dict类型。Path
/Query
操作不起作用deprecated
: 是否过期,bool
类型,默认Falseinclude_in_schema
: Swagger UI中是否添加对参数的说明,bool
类型,默认True当然,Body
、Query
和Path
也可以使用上面的这些参数!!!