リクエスト例データを宣言する¶
アプリが受け取る可能性のあるデータの例を宣言できます。
いくつかの方法を以下に示します。
Pydanticモデルの追加JSONスキーマデータ¶
Pydanticモデルに対して、生成されたJSONスキーマに追加されるexamplesを宣言できます。
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
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
class Config:
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
class Config:
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ドキュメントで使用されます。
Pydanticバージョン2では、Pydanticのドキュメント: Configurationで説明されているように、dictを受け取る属性model_configを使用します。
生成されたJSONスキーマに表示したい追加データ(examplesを含む)を含むdictで"json_schema_extra"を設定できます。
Pydanticバージョン1では、Pydanticのドキュメント: Schema customizationで説明されているように、内部クラスConfigとschema_extraを使用します。
生成されたJSONスキーマに表示したい追加データ(examplesを含む)を含むdictでschema_extraを設定できます。
ヒント
同じ手法を使用してJSONスキーマを拡張し、独自のカスタム追加情報を追加できます。
たとえば、フロントエンドのユーザーインターフェースなどのメタデータを追加するために使用できます。
情報
OpenAPI 3.1.0(FastAPI 0.99.0以降で使用)は、JSONスキーマ標準の一部であるexamplesのサポートを追加しました。
それ以前は、単一の例を示すキーワードexampleのみをサポートしていました。これはOpenAPI 3.1.0でもまだサポートされていますが、非推奨であり、JSONスキーマ標準の一部ではありません。したがって、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スキーマ - OpenAPIにおけるexamples¶
いずれかを使用する場合
Path()Query()Header()Cookie()Body()Form()File()
OpenAPI内のJSONスキーマに追加される追加情報を含むexamplesのグループを宣言することもできます。
examplesを含むBody¶
ここでは、Body()で期待されるデータの例を1つ含む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,
}
],
),
],
):
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
from typing import Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
from typing_extensions import Annotated
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
from typing import Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
from typing_extensions import Annotated
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スキーマの一部になります。
ただし、この記事の執筆時点では、ドキュメントUIを表示する役割を担うツールであるSwagger UIは、JSONスキーマのデータに複数の例を表示することをサポートしていません。しかし、回避策については以下をご覧ください。
OpenAPI固有のexamples¶
JSONスキーマがexamplesをサポートする以前から、OpenAPIはexamplesと呼ばれる別のフィールドをサポートしていました。
このOpenAPI固有のexamplesは、OpenAPI仕様の別のセクションにあります。各JSONスキーマの内部ではなく、各パス操作の詳細に含まれます。
そしてSwagger UIは、この特定のexamplesフィールドを以前からサポートしていました。したがって、これを使用してドキュメントUIでさまざまな例を表示できます。
このOpenAPI固有のフィールドexamplesの形式は、追加情報(リストではなく)を伴う複数の例を持つdictであり、これもOpenAPIに追加されます。
これは、OpenAPIに含まれる各JSONスキーマの内部ではなく、外部のパス操作に直接含まれます。
openapi_examplesパラメータの使用¶
FastAPIでOpenAPI固有のexamplesをパラメータ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
from typing import Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
from typing_extensions import Annotated
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例¶
Body()にopenapi_examplesが追加されると、/docsは次のようになります。

技術的な詳細¶
ヒント
すでにFastAPIバージョン0.99.0以降を使用している場合は、これらの詳細はスキップしても構いません。
OpenAPI 3.1.0が利用可能になる前の古いバージョンにより関連性があります。
これは、簡単なOpenAPIとJSONスキーマの歴史の授業と考えることができます。🤓
Warning
これらは、標準のJSONスキーマとOpenAPIに関する非常に技術的な詳細です。
上記のアイデアがすでに機能している場合は、それで十分かもしれません。これらの詳細は必要ないかもしれませんので、自由にスキップしてください。
OpenAPI 3.1.0より前は、OpenAPIはJSONスキーマの古い修正バージョンを使用していました。
JSONスキーマには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スキーマのexamplesフィールド¶
しかし、その後JSONスキーマは、新しいバージョンの仕様にexamplesフィールドを追加しました。
そして、新しいOpenAPI 3.1.0は、この新しいフィールドexamplesを含む最新バージョン(JSON Schema 2020-12)に基づいています。
そして現在、この新しいexamplesフィールドは、現在非推奨となっている古い単一の(カスタム)exampleフィールドよりも優先されます。
JSONスキーマのこの新しいexamplesフィールドは、OpenAPIの他の場所(上記で説明)のように追加のメタデータを持つ辞書ではなく、単なる例のlistです。
情報
OpenAPI 3.1.0がJSONスキーマとのこの新しいシンプルな統合でリリースされた後も、しばらくの間、自動ドキュメントを提供するツールであるSwagger UIはOpenAPI 3.1.0をサポートしていませんでした(バージョン5.0.0以降はサポートしています🎉)。
そのため、FastAPIの0.99.0以前のバージョンは、3.1.0より古いバージョンのOpenAPIを使用していました。
PydanticとFastAPIのexamples¶
Pydanticモデル内にschema_extraまたはField(examples=["something"])を使用してexamplesを追加すると、その例はそのPydanticモデルのJSONスキーマに追加されます。
そして、そのPydanticモデルのJSONスキーマは、APIのOpenAPIに含まれ、ドキュメントUIで使用されます。
FastAPIの0.99.0より前のバージョン(0.99.0以降は新しいOpenAPI 3.1.0を使用)では、他のユーティリティ(Query()、Body()など)でexampleまたはexamplesを使用した場合、それらの例はデータを記述するJSONスキーマに追加されず(OpenAPI自身のJSONスキーマバージョンにも)、OpenAPIのパス操作宣言に直接追加されました(JSONスキーマを使用するOpenAPIの部分の外側)。
しかし、FastAPI 0.99.0以降がOpenAPI 3.1.0(JSON Schema 2020-12を使用)とSwagger UI 5.0.0以降を使用するようになったため、すべてがより一貫性があり、例はJSONスキーマに含まれるようになりました。
Swagger UIとOpenAPI固有のexamples¶
さて、Swagger UIが複数のJSONスキーマの例をサポートしていなかったため(2023年8月26日現在)、ユーザーはドキュメントに複数の例を表示する方法がありませんでした。
それを解決するために、FastAPI 0.103.0は、新しいパラメータopenapi_examplesで同じ古いOpenAPI固有のexamplesフィールドを宣言するサポートを追加しました。🤓
概要¶
以前は歴史があまり好きではないと言っていましたが...今や「技術史」のレッスンをしているとは。😅
要するに、FastAPI 0.99.0以降にアップグレードすれば、物事ははるかにシンプルで、一貫性があり、直感的になり、これらの歴史的な詳細をすべて知る必要はありません。😎