声明请求示例数据¶
您可以声明您的应用程序可以接收的数据示例。
这里有几种方法可以做到。
Pydantic 模型中的额外 JSON Schema 数据¶
您可以为 Pydantic 模型声明 examples,这些示例将添加到生成的 JSON Schema 中。
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
model_config = {
"json_schema_extra": {
"examples": [
{
"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
🤓 其他版本和变体
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
model_config = {
"json_schema_extra": {
"examples": [
{
"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
这些额外信息将按原样添加到该模型的 JSON Schema 输出中,并将在 API 文档中使用。
您可以使用 model_config 属性,该属性接受一个 dict,如 Pydantic 文档:配置 中所述。
您可以使用包含任何您希望显示在生成的 JSON Schema 中的额外数据的 dict 来设置 "json_schema_extra",包括 examples。
提示
您可以使用相同的技术来扩展 JSON Schema 并添加您自己的自定义额外信息。
例如,您可以使用它来为前端用户界面添加元数据等。
信息
OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 examples 的支持,这是 JSON Schema 标准的一部分。
在此之前,它只支持带有单个示例的 example 关键字。OpenAPI 3.1.0 仍然支持这一点,但已弃用,并且不是 JSON Schema 标准的一部分。因此,建议您将 example 迁移到 examples。 🤓
您可以在本页末尾阅读更多内容。
Field 的附加参数¶
在使用 Pydantic 模型的 Field() 时,您还可以声明额外的 examples。
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str = Field(examples=["Foo"])
description: str | None = Field(default=None, examples=["A very nice Item"])
price: float = Field(examples=[35.4])
tax: float | None = Field(default=None, examples=[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
🤓 其他版本和变体
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str = Field(examples=["Foo"])
description: Union[str, None] = Field(default=None, examples=["A very nice Item"])
price: float = Field(examples=[35.4])
tax: Union[float, None] = Field(default=None, examples=[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
JSON Schema 中的 examples - OpenAPI¶
在使用任何以下方法时:
Path()Query()Header()Cookie()Body()Form()File()
您还可以声明一组 examples,并附带其他信息,这些信息将被添加到 **OpenAPI** 中其 **JSON Schemas** 的内部。
带有 examples 的 Body¶
在这里,我们传递 examples,其中包含一个数据示例,该数据将在 Body() 中使用。
from typing import Annotated
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(
item_id: int,
item: Annotated[
Item,
Body(
examples=[
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
}
],
),
],
):
results = {"item_id": item_id, "item": item}
return results
🤓 其他版本和变体
from typing import Annotated, Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
@app.put("/items/{item_id}")
async def update_item(
item_id: int,
item: Annotated[
Item,
Body(
examples=[
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
}
],
),
],
):
results = {"item_id": item_id, "item": item}
return results
提示
如果可能,请优先使用 Annotated 版本。
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(
item_id: int,
item: Item = Body(
examples=[
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
}
],
),
):
results = {"item_id": item_id, "item": item}
return results
提示
如果可能,请优先使用 Annotated 版本。
from typing import Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
@app.put("/items/{item_id}")
async def update_item(
item_id: int,
item: Item = Body(
examples=[
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
}
],
),
):
results = {"item_id": item_id, "item": item}
return results
文档 UI 中的示例¶
使用上述任何方法,在 /docs 中看起来都会像这样。

带有多个 examples 的 Body¶
当然,您也可以传递多个 examples。
from typing import Annotated
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Annotated[
Item,
Body(
examples=[
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
{
"name": "Bar",
"price": "35.4",
},
{
"name": "Baz",
"price": "thirty five point four",
},
],
),
],
):
results = {"item_id": item_id, "item": item}
return results
🤓 其他版本和变体
from typing import Annotated, Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Annotated[
Item,
Body(
examples=[
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
{
"name": "Bar",
"price": "35.4",
},
{
"name": "Baz",
"price": "thirty five point four",
},
],
),
],
):
results = {"item_id": item_id, "item": item}
return results
提示
如果可能,请优先使用 Annotated 版本。
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Item = Body(
examples=[
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
{
"name": "Bar",
"price": "35.4",
},
{
"name": "Baz",
"price": "thirty five point four",
},
],
),
):
results = {"item_id": item_id, "item": item}
return results
提示
如果可能,请优先使用 Annotated 版本。
from typing import Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Item = Body(
examples=[
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
{
"name": "Bar",
"price": "35.4",
},
{
"name": "Baz",
"price": "thirty five point four",
},
],
),
):
results = {"item_id": item_id, "item": item}
return results
这样做时,这些示例将成为该请求体数据内部 **JSON Schema** 的一部分。
但是,在写作时(2023-08-26),负责显示文档 UI 的工具 Swagger UI 不支持为 **JSON Schema** 中的数据显示多个示例。但请继续阅读下文以了解解决方法。
OpenAPI 特定的 examples¶
在 **JSON Schema** 支持 examples 之前,OpenAPI 就已经支持一个名为 examples 的不同字段。
这个 **OpenAPI 特定的** examples 字段位于 OpenAPI 规范的另一个部分。它位于 **每个*操作路径*的详细信息** 中,而不是每个 JSON Schema 的内部。
Swagger UI 一直支持这个特定的 examples 字段。因此,您可以使用它来 **在文档 UI 中显示** 不同的 **示例**。
这个 OpenAPI 特定的 examples 字段的结构是一个 **多个示例** 的 dict(而不是 list),每个示例都包含将添加到 **OpenAPI** 的额外信息。
这不包含在 OpenAPI 中的每个 JSON Schema 的内部,而是直接放在*操作路径*外部。
使用 openapi_examples 参数¶
您可以使用 openapi_examples 参数在 FastAPI 中声明 OpenAPI 特定的 examples,用于:
Path()Query()Header()Cookie()Body()Form()File()
dict 的键标识每个示例,每个值是另一个 dict。
examples 中每个特定的示例 dict 可以包含:
summary:示例的简短描述。description:一个可以包含 Markdown 文本的长描述。value:这是实际显示的示例,例如一个dict。externalValue:value的替代选项,一个指向示例的 URL。虽然这可能不如value被许多工具支持。
您可以这样使用它:
from typing import Annotated
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Annotated[
Item,
Body(
openapi_examples={
"normal": {
"summary": "A normal example",
"description": "A **normal** item works correctly.",
"value": {
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
},
"converted": {
"summary": "An example with converted data",
"description": "FastAPI can convert price `strings` to actual `numbers` automatically",
"value": {
"name": "Bar",
"price": "35.4",
},
},
"invalid": {
"summary": "Invalid data is rejected with an error",
"value": {
"name": "Baz",
"price": "thirty five point four",
},
},
},
),
],
):
results = {"item_id": item_id, "item": item}
return results
🤓 其他版本和变体
from typing import Annotated, Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Annotated[
Item,
Body(
openapi_examples={
"normal": {
"summary": "A normal example",
"description": "A **normal** item works correctly.",
"value": {
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
},
"converted": {
"summary": "An example with converted data",
"description": "FastAPI can convert price `strings` to actual `numbers` automatically",
"value": {
"name": "Bar",
"price": "35.4",
},
},
"invalid": {
"summary": "Invalid data is rejected with an error",
"value": {
"name": "Baz",
"price": "thirty five point four",
},
},
},
),
],
):
results = {"item_id": item_id, "item": item}
return results
提示
如果可能,请优先使用 Annotated 版本。
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Item = Body(
openapi_examples={
"normal": {
"summary": "A normal example",
"description": "A **normal** item works correctly.",
"value": {
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
},
"converted": {
"summary": "An example with converted data",
"description": "FastAPI can convert price `strings` to actual `numbers` automatically",
"value": {
"name": "Bar",
"price": "35.4",
},
},
"invalid": {
"summary": "Invalid data is rejected with an error",
"value": {
"name": "Baz",
"price": "thirty five point four",
},
},
},
),
):
results = {"item_id": item_id, "item": item}
return results
提示
如果可能,请优先使用 Annotated 版本。
from typing import Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Item = Body(
openapi_examples={
"normal": {
"summary": "A normal example",
"description": "A **normal** item works correctly.",
"value": {
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
},
"converted": {
"summary": "An example with converted data",
"description": "FastAPI can convert price `strings` to actual `numbers` automatically",
"value": {
"name": "Bar",
"price": "35.4",
},
},
"invalid": {
"summary": "Invalid data is rejected with an error",
"value": {
"name": "Baz",
"price": "thirty five point four",
},
},
},
),
):
results = {"item_id": item_id, "item": item}
return results
文档 UI 中的 OpenAPI 示例¶
将 openapi_examples 添加到 Body() 后,/docs 将显示如下:

技术细节¶
提示
如果您已经在使用 **FastAPI** 版本 **0.99.0 或更高版本**,您可能可以 **跳过** 这些细节。
它们对于旧版本(OpenAPI 3.1.0 可用之前)更相关。
您可以将此视为一次简短的 OpenAPI 和 JSON Schema **历史课程**。 🤓
警告
这些是关于 **JSON Schema** 和 **OpenAPI** 标准的技术细节。
如果上述想法对您已经有效,那可能就足够了,您可能不需要这些细节,可以随意跳过它们。
在 OpenAPI 3.1.0 之前,OpenAPI 使用了一个更旧且修改过的 **JSON Schema** 版本。
JSON Schema 没有 examples,所以 OpenAPI 添加了自己的 example 字段到它自己的修改版中。
OpenAPI 还向规范的其他部分添加了 example 和 examples 字段:
Parameter Object(在规范中),FastAPI 的Path()Query()Header()Cookie()
Request Body Object,在content字段中,在Media Type Object(在规范中),FastAPI 的Body()File()Form()
信息
这个旧的 OpenAPI 特定的 examples 参数在 FastAPI 0.103.0 中已成为 openapi_examples。
JSON Schema 的 examples 字段¶
但是后来 JSON Schema 在新版本的规范中添加了一个 examples 字段。
然后新的 OpenAPI 3.1.0 基于包含这个新字段 examples 的最新版本(JSON Schema 2020-12)。
现在,这个新的 examples 字段优先于旧的单个(自定义)example 字段,后者现在已弃用。
JSON Schema 中的这个新的 examples 字段 **只是一个示例的 list**,而不是像 OpenAPI 中其他地方(如上所述)那样包含额外元数据的 dict。
信息
即使在 OpenAPI 3.1.0 发布并与 JSON Schema 进行更简单集成之后,一段时间以来,提供自动文档的工具 Swagger UI 也不支持 OpenAPI 3.1.0(自 5.0.0 版本起支持 🎉)。
因此,FastAPI 早于 0.99.0 的版本仍然使用低于 3.1.0 的 OpenAPI 版本。
Pydantic 和 FastAPI 的 examples¶
当您使用 schema_extra 或 Field(examples=["something"]) 在 Pydantic 模型中添加 examples 时,该示例将被添加到该 Pydantic 模型的 **JSON Schema** 中。
而该 Pydantic 模型的 **JSON Schema** 会被包含在您 API 的 **OpenAPI** 中,然后在文档 UI 中使用。
在 FastAPI 0.99.0 之前的版本(0.99.0 及更高版本使用更新的 OpenAPI 3.1.0)中,当您使用 example 或 examples 以及其他任何工具(Query()、Body() 等)时,这些示例不会被添加到描述该数据的 JSON Schema 中(甚至不会添加到 OpenAPI 自有的 JSON Schema 版本中),而是直接添加到 OpenAPI 中*操作路径*的声明中(在 OpenAPI 使用 JSON Schema 的部分之外)。
但现在,FastAPI 0.99.0 及更高版本使用 OpenAPI 3.1.0,它使用 JSON Schema 2020-12,Swagger UI 5.0.0 及更高版本,一切都更加一致,并且示例已包含在 JSON Schema 中。
Swagger UI 和 OpenAPI 特定的 examples¶
现在,由于 Swagger UI 不支持多个 JSON Schema 示例(截至 2023-08-26),用户无法在文档中显示多个示例。
为了解决这个问题,FastAPI 0.103.0 **增加了支持**,可以使用新的 openapi_examples 参数声明旧的 **OpenAPI 特定的** examples 字段。 🤓
总结¶
我以前说过我不喜欢历史……看看我现在,还在给“技术历史”授课。😅
总之,**升级到 FastAPI 0.99.0 或更高版本**,事情会变得更加 **简单、一致和直观**,您无需了解所有这些历史细节。😎