FastAPI(15)- 声明请求示例数据
前言
- FastAPI 可以给 Pydantic Model 或者路径函数声明需要接收的请求示例,而且可以显示在 OpenAPI 文档上
- 有几种方式,接下来会详细介绍
Pydantic 的 schema_extra
可以使用 Config cass 和 schema_extra 为 Pydantic Model 声明一个示例值
from typing import Optional import uvicorn from pydantic import BaseModel from fastapi import FastAPI app = FastAPI() class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None # 内部类,固定写法 class Config: schema_extra = { "example": { "name": "Foo", "description": "A very nice Item", "price": 35.4, "tax": 3.2, } } @app.put("/items/{item_id}") async def update_item(item_id: int, item: Item): results = {"item_id": item_id, "item": item} return results if __name__ == "__main__": uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True, debug=True)
查看 Swagger API 文档
无论是 Example Value 还是 Schema 都会显示声明的示例值
Field 添加额外的参数
使用 Pydantic 的 Field() 时,可以将任何其他任意参数添加到函数参数中,来声明 JSON Schema 的额外信息
Field 的 extra 参数
默认 Field 是没有 example 参数的,而 **extra 就是关键字参数,表示可以添加其他任意参数,和常见的 **kwargs 是一个作用哦
添加额外的参数: example 参数
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/9/19 9:40 下午 # file: 12_model.py """ from typing import Optional import uvicorn from pydantic import BaseModel, Field from fastapi import FastAPI app = FastAPI() class Item(BaseModel): # 给每个字段加上了 example 参数 name: str = Field(..., example="小菠萝") description: Optional[str] = Field(None, example="描述") price: float = Field(..., example=1.11) tax: Optional[float] = Field(None, example=3.2) @app.put("/items/{item_id}") async def update_item(item_id: int, item: Item): results = {"item_id": item_id, "item": item} return results
一定要命名为 example 吗?
- 不一定,命名为其他也可以
- 但是只有添加名为 example 的参数,Swagger API 上的 Example Value 才会显示这里传的参数值(示例值)
重点
- 因为这里的 example 参数是额外添加的参数,所以不会进行数据验证
- 比如字段类型声明为 str,example 参数传了数组也不会报错
查看 Swagger API 文档
它是针对每个字段设置的示例值,所以会显示在字段下
OpenAPI 中的 example、examples 参数
当使用 FastAPI 提供的
- Path()
- Query()
- Header()
- Cookie()
- Body()
- Form()
- File()
可以声明一个 example 或 examples 参数,FastAPI 会自动将 example、examples 的值添加到 OpenAPI 文档中
总结
Pydantic 并没有直接支持 example 参数,而 FastAPI 进行了扩展,直接支持添加 example、examples 参数
使用 Body() ,添加 example 参数
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/9/19 9:40 下午 # file: 12_model.py """ from typing import Optional import uvicorn from pydantic import BaseModel from fastapi import FastAPI, Body app = FastAPI() class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None @app.put("/items/{item_id}") async def update_item( item_id: int, item: Item = Body( default=..., description="描述", # 添加一个 example 参数 example={ "name": "body name", "description": "body 描述", "price": 3.33, "tax": 5.55 }, ), ): results = {"item_id": item_id, "item": item} return results if __name__ == "__main__": uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True, debug=True)
查看 Swagger API 文档
Schema 并不会显示 example 的值哦
使用 Body() ,添加 examples 参数
examples
本身是一个 dict,每个键标识一个具体的示例,而键对应的值也是一个 dict
每个示例 dict 可以包含
- summary:简短描述
- description:可以包含 markdown 文本的长描述
- value:显示的示例值
- externalValue:替代值,指向示例的 URL(不怎么用)
实际代码
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/9/19 9:40 下午 # file: 12_model.py """ from typing import Optional import uvicorn from pydantic import BaseModel, Field from fastapi import FastAPI, Body app = FastAPI() class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None @app.put("/items/{item_id}") async def update_item( *, item_id: int, item: Item = Body( default=..., # 三个键,代表三个不一样的示例值 examples={ "normal": { "summary": "正常的栗子", "description": "A **normal** item works correctly.", "value": { "name": "Foo", "description": "A very nice Item", "price": 35.4, "tax": 3.2, }, }, "converted": { "summary": "会自动转换类型的栗子", "description": "FastAPI can convert price `strings` to actual `numbers` automatically", "value": { "name": "Bar", "price": "35.4", }, }, "invalid": { "summary": "校验失败的栗子", "value": { "name": "Baz", "price": "thirty five point four", }, }, }, ), ): results = {"item_id": item_id, "item": item} return results if __name__ == "__main__": uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True, debug=True)
查看 Swagger API 文档