Декларування прикладів вхідних даних¶
Ви можете задати приклади даних, які Ваш застосунок може отримувати.
Ось кілька способів, як це зробити.
Додаткові дані JSON-схеми в моделях Pydantic¶
Ви можете задати examples для моделі Pydantic, які буде додано до згенерованої JSON-схеми.
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
🤓 Other versions and variants
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-схеми для цієї моделі, і вона буде використана в документації до API.
Ви можете використати атрибут model_config, який приймає dict, як описано в документації Pydantic: Configuration.
Ви можете встановити "json_schema_extra" як dict, що містить будь-які додаткові дані, які Ви хочете відобразити у згенерованій JSON-схемі, включаючи examples.
Порада
Ви можете використати ту ж техніку, щоб розширити JSON-схему і додати власну додаткову інформацію.
Наприклад, Ви можете використати її для додавання метаданих для інтерфейсу користувача на фронтенді тощо.
Інформація
OpenAPI 3.1.0 (який використовується починаючи з FastAPI 0.99.0) додав підтримку examples, що є частиною стандарту JSON-схеми.
До цього підтримувався лише ключ example з одним прикладом. Він все ще підтримується в OpenAPI 3.1.0, але є застарілим і не входить до стандарту JSON Schema. Тому рекомендується перейти з example на examples. 🤓
Більше про це можна прочитати в кінці цієї сторінки.
Додаткові аргументи Field¶
Коли ви використовуєте Field() у моделях Pydantic, Ви також можете вказати додаткові 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
🤓 Other versions and variants
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
examples у JSON-схемі — OpenAPI¶
При використанні будь-кого з наступного:
Path()Query()Header()Cookie()Body()Form()File()
Ви також можете задати набір examples з додатковою інформацією, яка буде додана до їхніх JSON-схем у OpenAPI.
Body з examples¶
Тут ми передаємо 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
🤓 Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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:

Body з кількома examples¶
Звичайно, Ви також можете передати кілька 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
🤓 Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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-схеми для цих даних тіла.
Втім, на момент написання цього (час написання цього), Swagger UI — інструмент, який відповідає за відображення UI документації — не підтримує показ кількох прикладів для даних у JSON-схемі. Але нижче можна прочитати про обхідний шлях.
Специфічні для OpenAPI examples¶
Ще до того, як JSON-схема почала підтримувати examples, OpenAPI вже мала підтримку іншого поля, яке також називається examples.
Це специфічне для OpenAPI поле examples розміщується в іншому розділі специфікації OpenAPI. Воно розміщується в деталях кожної операції шляху, а не всередині кожної JSON-схеми.
І Swagger UI вже давно підтримує це поле examples. Тому Ви можете використовувати його, щоб відображати різні приклади в UI документації.
Форма цього специфічного для OpenAPI поля examples — це dict з кількома прикладами (а не list), кожен із яких має додаткову інформацію, яка також буде додана до OpenAPI.
Воно не включається всередину кожної JSON-схеми, що міститься в OpenAPI, воно розміщується зовні, безпосередньо в операції шляху.
Використання параметра openapi_examples¶
Ви можете оголосити специфічні для OpenAPI examples у FastAPI за допомогою параметра openapi_examples для:
Path()Query()Header()Cookie()Body()Form()File()
Ключі dict ідентифікують кожен приклад, а кожне значення — це інший dict.
Кожен специфічний dict прикладу в examples може містити:
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
🤓 Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Приклади OpenAPI в UI документації¶
З 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 тепер називається openapi_examples, починаючи з FastAPI 0.103.0.
Поле examples у JSON Schema¶
Пізніше JSON Schema додала поле examples у нову версію специфікації.
А потім новий OpenAPI 3.1.0 базувався на найновішій версії (JSON Schema 2020-12), яка включала це нове поле examples.
І тепер це нове поле examples має вищий пріоритет за старе одиночне (і кастомне) поле example, яке тепер є застарілим.
Це нове поле examples у JSON Schema — це просто list прикладів, а не dict з додатковими метаданими, як в інших місцях OpenAPI (описаних вище).
Інформація
Навіть після релізу OpenAPI 3.1.0 з цією новою простішою інтеграцією з JSON Schema, протягом певного часу Swagger UI, інструмент, який надає автоматичну документацію, не підтримував OpenAPI 3.1.0 (тепер підтримує, починаючи з версії 5.0.0 🎉).
Через це версії FastAPI до 0.99.0 все ще використовували версії OpenAPI нижчі за 3.1.0.
examples у Pydantic і FastAPI¶
Коли Ви додаєте examples у модель Pydantic через schema_extra або Field(examples=["something"]), цей приклад додається до JSON Schema для цієї моделі Pydantic.
І ця JSON Schema Pydantic-моделі включається до OpenAPI Вашого API, а потім використовується в UI документації.
У версіях FastAPI до 0.99.0 (0.99.0 і вище використовують новіший OpenAPI 3.1.0), коли Ви використовували example або examples з будь-якими іншими утилітами (Query(), Body() тощо), ці приклади не додавалися до JSON Schema, що описує ці дані (навіть не до власної версії JSON Schema в OpenAPI), натомість вони додавалися безпосередньо до декларації операції шляху в 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 або вище — і все стане значно простішим, узгодженим та інтуїтивно зрозумілим, і Вам не доведеться знати всі ці історичні деталі. 😎