L12 ch01 — Pydantic BaseModel
テクノロジ系 / L12 pydantic — Pydantic モデルによる型安全
L12 ch01 — Pydantic BaseModel
型安全な API へ進化
ゴール
BaseModelを継承してリクエスト型を定義- FastAPI が自動で 422 バリデーションを返す
- response_model で出力型も制御
なぜ Pydantic を使うか
❌ Request.json() の問題:
- 引数の型が確定しない
- 必須フィールドの検証を手で書く
- IDE 補完が効かない
✅ Pydantic:
- 型ヒントから自動生成 + 自動検証
- IDE 補完が完璧
- Swagger UI に自動反映
基本
from pydantic import BaseModel
from fastapi import FastAPI
app = FastAPI()
class Task(BaseModel):
title: str
done: bool = False
@app.post("/tasks")
def create_task(task: Task):
return {"received": task.title, "done": task.done}動作
# ✅ 正しい
curl -X POST /tasks -d '{"title": "x"}'
# → {"received": "x", "done": false}
# ❌ title 欠落
curl -X POST /tasks -d '{"done": true}'
# → 422 + {"detail": [{"loc": ["body", "title"], ...}]}フィールド追加
class Task(BaseModel):
title: str
done: bool = False
priority: int = 1 # ← 追加
tags: list[str] = []→ 既存のリクエストを壊さずに拡張可能 (デフォルト値あり)
response_model
class TaskOut(BaseModel):
id: int
title: str
done: bool
@app.get("/tasks/{id}", response_model=TaskOut)
def get(id: int):
return tasks[id] # 余計なフィールドは自動で除外→ DB の生データから 公開して良い形 に絞れる
Field でバリデーション強化
from pydantic import Field
class Task(BaseModel):
title: str = Field(min_length=1, max_length=100)
priority: int = Field(ge=1, le=5) # 1-5 範囲drill
drill/ — fill-basemodel, add-field
力試ししたい方は クイズ形式の演習(任意) もあります。読むだけでも十分です。