fastapi-参数校验

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}

fastapi-参数校验_第1张图片

可以看到,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类型,默认False
  • include_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}

fastapi-参数校验_第2张图片

在上面,我们可以看到,我们想将该参数设置为非必须,我们只需要给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,而是表单字段时,要使用到FormForm参数的使用方式与PathQuery一样,使用如下:

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}

fastapi-参数校验_第3张图片

Form支持的其他参数与QueryPath基本相同!

文件参数校验

服务端介绍客户端上传的文件有两种方式:FileUploadFile。使用如下:

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}

fastapi-参数校验_第4张图片

两种方式都是通过multipart/form-data形式接收文件的!

UploadFilebytes相比有更多优势:

  • 使用spooled文件:
  • 存储在内存的文件超出最大上限时,FastAPI会把文件存入磁盘;
  • 这种方式更适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存;
  • 可获取上传文件的元数据;
  • 自带file-likeasync 接口;
  • 暴露的PythonSpooledTemporaryFile对象,可直接传递给其他预期file-like对象的库

UploadFile具有如下属性:

  • filename: 上传文件名字符串(str),例如,aaa.png
  • content_type: 内容类型字符串,例如,image/png
  • file: 一个SpooledTemporaryFile(file-like对象)对象

UploadFile支持以下async方法:

  • write(data): 把data(strbytes)写入文件
  • 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}

fastapi-参数校验_第5张图片

除此之外,请求体参数也可以向查询参数一样,定义在方法的参数里面。此时,我们就需要使用到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支持的其他参数QueryPath基本相同,但是exampleBody中不起作用

Field常见参数如下:

  • default: 默认值,任何类型。 当设置了该值,表明该参数非必须参数
  • default_factory: 生成的默认值的函数,接收一个Callable类型。defaultdefault_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类型,默认False
  • include_in_schema: Swagger UI中是否添加对参数的说明,bool类型,默认True

当然,BodyQueryPath也可以使用上面的这些参数!!!

你可能感兴趣的:(fastapi,fastapi,python)