前言
- FastAPI 可以给 Pydantic Model 或者路径函数声明需要接收的请求示例,而且可以显示在 OpenAPI 文档上
- 有几种方式,接下来会详细介绍
Pydantic 的 schema_extra
可以使用 Config cass 和 schema_extra 为 Pydantic Model 声明一个示例值
代码语言:javascript复制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 是一个作用哦
关键字参数教程
Field 教程
添加额外的参数: example 参数
代码语言:javascript复制#!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 参数
代码语言:javascript复制#!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(不怎么用)
实际代码
代码语言:javascript复制#!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)