リクエストボディ¶
クライアント(ブラウザなど)からAPIにデータを送信する必要がある場合は、**リクエストボディ**として送信します。
**リクエスト**ボディは、クライアントからAPIに送信されるデータです。**レスポンス**ボディは、APIがクライアントに送信するデータです。
APIはほとんどの場合、**レスポンス**ボディを送信する必要があります。しかし、クライアントは常に**リクエストボディ**を送信する必要はありません。パスのみをリクエストする場合や、クエリパラメータを付けてリクエストするだけで、ボディを送信しない場合もあります。
**リクエスト**ボディを宣言するには、Pydanticモデルをそのすべての機能と利点とともに使用します。
情報
データを送信するには、POST
(より一般的)、PUT
、DELETE
、またはPATCH
のいずれかを使用する必要があります。
GET
リクエストでボディを送信すると、仕様では未定義の動作になりますが、FastAPIでは非常に複雑な/極端なユースケースのためにのみサポートされています。
推奨されていないため、Swagger UIを使用したインタラクティブドキュメントでは、GET
を使用する場合のボディのドキュメントは表示されず、途中のプロキシではサポートされない場合があります。
PydanticのBaseModel
をインポートする¶
まず、pydantic
からBaseModel
をインポートする必要があります。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
データモデルを作成する¶
次に、BaseModel
を継承するクラスとしてデータモデルを宣言します。
すべての属性に標準のPython型を使用します。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
クエリパラメータを宣言する場合と同じように、モデル属性にデフォルト値がある場合、それは必須ではありません。そうでない場合は必須です。オプションにするには、None
を使用します。
たとえば、上記のモデルは、JSON "object
"(またはPython dict
)を次のように宣言します。
{
"name": "Foo",
"description": "An optional description",
"price": 45.2,
"tax": 3.5
}
...description
とtax
はオプション(デフォルト値はNone
)であるため、このJSON "object
"も有効です。
{
"name": "Foo",
"price": 45.2
}
パラメータとして宣言する¶
**パス操作**に追加するには、パス パラメータとクエリ パラメータを宣言したのと同じ方法で宣言します。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
...そして、その型を作成したモデル`Item`として宣言します。
結果¶
そのPython型の宣言だけで、**FastAPI**は次のことを行います。
- リクエストのボディをJSONとして読み取ります。
- 対応する型に変換します(必要な場合)。
- データを検証します。
- データが無効な場合、正確な位置と無効なデータの内容を示す、分かりやすいエラーが返されます。
- 受信したデータは、パラメータ
item
で渡されます。- 関数で
Item
型として宣言されているため、すべての属性とその型に対して、エディタのサポート(補完など)が利用できます。
- 関数で
- モデルのJSON Schema定義が生成されます。プロジェクトにとって意味がある場合は、他の場所でも使用できます。
- これらのスキーマは、生成されたOpenAPIスキーマの一部となり、自動ドキュメントUIで使用されます。
自動ドキュメント¶
モデルのJSONスキーマは、生成されたOpenAPIスキーマの一部となり、インタラクティブなAPIドキュメントに表示されます。
また、APIドキュメント内の、それらを必要とする各パス操作でも使用されます。
エディタサポート¶
エディタでは、関数内で、あらゆる場所で型ヒントと補完が得られます(Pydanticモデルではなくdict
を受け取った場合は、これは起こりません)。
また、不正な型操作に対するエラーチェックも受けられます。
これは偶然ではなく、フレームワーク全体がこの設計を中心に構築されています。
また、すべての実装の前に、設計段階で徹底的にテストされ、すべて のエディタで動作することが確認されています。
これをサポートするために、Pydantic自体にもいくつかの変更が加えられました。
前のスクリーンショットは、Visual Studio Codeで撮影されました。
しかし、PyCharmや他のほとんどのPythonエディタでも、同じエディタサポートが得られます。
ヒント
エディタとしてPyCharmを使用する場合は、Pydantic PyCharmプラグインを使用できます。
これは、以下の機能により、Pydanticモデルのエディタサポートを向上させます。
- 自動補完
- 型チェック
- リファクタリング
- 検索
- インスペクション
モデルの使用¶
関数内では、モデルオブジェクトのすべての属性に直接アクセスできます。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
リクエストボディ + パスパラメータ¶
パスパラメータとリクエストボディを同時に宣言できます。
FastAPIは、パスパラメータに一致する関数パラメータはパスから取得し、Pydanticモデルとして宣言されている関数パラメータはリクエストボディから取得する必要があることを認識します。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.dict()}
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.dict()}
リクエストボディ + パス + クエリパラメータ¶
ボディ、パス、クエリパラメータをすべて同時に宣言することもできます。
FastAPIは、それぞれを認識し、正しい場所からデータを取得します。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: str | None = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: Union[str, None] = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result
関数パラメータは、次のように認識されます。
- パラメータがパスにも宣言されている場合、パスパラメータとして使用されます。
- パラメータが単一型(
int
、float
、str
、bool
など)の場合、クエリパラメータとして解釈されます。 - パラメータがPydanticモデルの型として宣言されている場合、リクエストボディとして解釈されます。
注意
FastAPIは、デフォルト値= None
のため、q
の値が必須ではないことを認識します。
str | None
(Python 3.10+) または Union
in Union[str, None]
(Python 3.8+) は、FastAPIによって値が必須ではないと判断するために使用されるわけではなく、デフォルト値が= None
であるため、必須ではないと判断されます。
しかし、型アノテーションを追加することで、エディタがより良いサポートを提供し、エラーを検出できるようになります。
Pydanticなし¶
Pydanticモデルを使用したくない場合は、Bodyパラメータを使用することもできます。Body - 複数のパラメータ: ボディ内の単一値のドキュメントを参照してください。