使用ライブラリ FastAPI FastAPIとは FastAPIの特徴 FastAPIの使い方 SQLAlchemy テーブル定義 データ取得 async/await対応版 Pydantic BaseModel uvicorn
使用ライブラリ
- FastAPI(Webフレームワーク)
- Pydantic(データバリデーション)
- SQLAlchemy(ORM)
FastAPI
FastAPIとは
Pythonの型ヒントに基づいてAPIを構築するためのモダンなWebフレームワーク。「フレームワーク」の回で紹介したマイクロフレームワークに分類される。
FastAPIの特徴
- 高速
- Pythonのフレームワークの中ではトップクラスのパフォーマンス
- Flaskに近い構文
- Flaskを学習したことがある人は学習コストが低い
- 非同期処理のサポート
- Python 3.5から導入されたasync/awaitがフレームワークレベルでサポートされている
- APIドキュメントの自動生成
- コードを書くだけでOpenAPIフォーマットのドキュメントが自動で作られる
- Swagger UI(対話的にAPIを試せる画面)とReDoc(読みやすいドキュメント画面)の2種類で表示できる
- 別途ドキュメントを手書きする必要がなく、コードとドキュメントが常に同期する
- 型チェックによるバリデーション
- 関数の引数に型を書くだけで、入力値の検証が自動で行われる
- 不正な値が来たら422エラーを自動で返す
- バリデーションにはPydanticが使われている
FastAPIの使い方
最もシンプルなFastAPI
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"} この数行だけで以下が実現される。
-
http://localhost:8000/にGETリクエストを送ると{"message": "Hello World"}が返る -
http://localhost:8000/docsでSwagger UIが表示される -
http://localhost:8000/redocでReDocが表示される
パスパラメータ
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id} -
/items/42にアクセスすると{"item_id": 42}が返る -
item_id: intと型注釈をつけることで、文字列が来た場合は自動で422エラーを返す
クエリパラメータ
from fastapi import FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return fake_items_db[skip : skip + limit] -
/items/?skip=1&limit=2でリストの1番目から2件取得できる - デフォルト値があるパラメータは省略可能
リクエストボディ(Pydanticモデル)
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
description: str | None = None
@app.post("/items/", status_code=201)
async def create_item(item: Item):
return item - POSTリクエストのボディをPydanticモデルとして受け取る
- JSONの自動パース、バリデーション、OpenAPIドキュメントへの反映が全て行われる
-
descriptionはOptional(省略可能)
PUT / PATCH / DELETE
class ItemUpdate(BaseModel):
name: str
price: float
description: str | None = None
class ItemPatch(BaseModel):
name: str | None = None
price: float | None = None
description: str | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: ItemUpdate):
return {"item_id": item_id, **item.model_dump()}
@app.patch("/items/{item_id}")
async def patch_item(item_id: int, item: ItemPatch):
return {"item_id": item_id, **item.model_dump(exclude_unset=True)}
@app.delete("/items/{item_id}", status_code=204)
async def delete_item(item_id: int):
return None - PUT: 全フィールドを送る(ItemUpdateの全フィールドが必須)
- PATCH: 変更したいフィールドだけ送る(ItemPatchの全フィールドがOptional)
- DELETE: レスポンスボディなし(204 No Content)
SQLAlchemy
FastAPIとよく一緒に使用されるORM(Object-Relational Mapping)の一つ。Pythonのクラスとデータベースのテーブルを対応付け、SQLを直接書かずにデータベース操作ができる。
テーブル定義
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "user"
id: Mapped[int] = mapped_column(primary_key=True)
email: Mapped[str] = mapped_column(unique=True, nullable=False)
password: Mapped[str] = mapped_column(nullable=False)
name: Mapped[str] = mapped_column(nullable=False) - Pythonのクラスがそのままデータベースのテーブル定義になる
- 型注釈(
Mapped[int]等)でカラムの型を表現する
データ取得
from sqlalchemy import select
from sqlalchemy.orm import Session
from .models import User
def get_user(db: Session, user_id: int):
return db.scalars(select(User).where(User.id == user_id)).first() -
select(User).where(User.id == user_id)でSQLのSELECT * FROM user WHERE id = ?に相当する処理を記述できる - SQLを直接書かずにPythonのコードとして表現できるため、型チェックやIDEの補完が効く
async/await対応版
from sqlalchemy.ext.asyncio import AsyncSession
async def get_user(db: AsyncSession, user_id: int):
result = await db.scalars(select(User).where(User.id == user_id))
return result.first() - AsyncSessionを使い、awaitをつける以外は同一
Pydantic BaseModel
APIの入出力データの構造を定義するためのクラス。FastAPIはPydanticモデルを使ってリクエスト/レスポンスのバリデーションとシリアライズを行う。
from pydantic import BaseModel, EmailStr
class UserIn(BaseModel):
username: str
password: str
email: EmailStr
full_name: str | None = None - 型に合わないデータが来たらバリデーションエラー(422)を自動で返す
-
EmailStrのように特殊な型を使うと、メールアドレスの形式チェックも自動で行われる - APIドキュメントにそのままスキーマとして反映される
uvicorn
FastAPIアプリケーションを実行するためのASGIサーバー。開発時も本番時もuvicornを使ってアプリケーションを起動する。
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 -
app.main:appは「app/main.pyファイルのapp変数」を指す -
--reloadをつけるとコード変更時に自動でサーバーが再起動する(開発時のみ使う) - 本番ではgunicorn + uvicorn workerや
--workersオプションで複数プロセスを起動するのが一般的



