FastAPIの dependencies.py
について詳しく解説
FastAPIでは 依存関係(Dependency Injection, DI) を活用することで、コードの再利用性を高め、保守性を向上させることができます。dependencies.py
は、この依存関係を管理するためのファイルです。
本記事では、dependencies.py
の役割、一般的な使い方、設計のポイントについて詳しく解説します。
1. dependencies.py
の役割
FastAPIにおける「依存関係」とは、リクエストごとに共通で利用する処理を関数として定義し、それをエンドポイントや他の関数で再利用する仕組みのことです。
例えば、以下のような処理を共通化するのに役立ちます。
- データベースのセッション管理
- 認証・認可の処理
- 共通のリクエストヘッダー処理
- 設定情報の取得
- キャッシュやログの処理
dependencies.py
に共通処理をまとめることで、コードの分離ができ、APIエンドポイントの記述をシンプルに保つことができます。
2. dependencies.py
の基本的な構成
データベースのセッション管理
データベースに接続するための Session
をリクエストごとに生成し、適切にクローズするための依存関係を定義します。
dependencies.py
from sqlalchemy.orm import Session
from fastapi import Depends
from app.database import SessionLocal
def get_db():
"""データベースセッションを取得する依存関係"""
db = SessionLocal()
try:
yield db
finally:
db.close()
この get_db
関数は、APIエンドポイント内で Depends(get_db)
を指定すると、自動的にデータベースのセッションを提供し、リクエストの処理が完了したらセッションをクローズしてくれます。
使用例(routers/user.py
)
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.dependencies import get_db
from app.models.user import User
router = APIRouter()
@router.get("/users/")
def read_users(db: Session = Depends(get_db)):
return db.query(User).all()
ポイント
db: Session = Depends(get_db)
により、get_db
関数で提供されたデータベースセッションを利用可能- セッションは
yield
によって適切に管理されるため、明示的にdb.close()
する必要なし
3. 認証・認可を dependencies.py
に分離する
FastAPIでは、認証情報(JWTトークンなど)を依存関係として管理することで、セキュリティを向上させることができます。
認証を行う依存関係
from fastapi import Depends, HTTPException, Security
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def get_current_user(token: str = Depends(oauth2_scheme)):
"""JWTトークンを検証し、ユーザー情報を取得"""
if not token or token != "valid_token": # 実際にはトークンを検証する処理が必要
raise HTTPException(status_code=401, detail="Invalid token")
return {"username": "test_user"}
使用例(routers/protected.py
)
from fastapi import APIRouter, Depends
from app.dependencies import get_current_user
router = APIRouter()
@router.get("/protected/")
def protected_route(user: dict = Depends(get_current_user)):
return {"message": f"Hello {user['username']}!"}
ポイント
Depends(get_current_user)
により、認証済みのユーザー情報を取得- 無効なトークンなら
401 Unauthorized
を返す - APIエンドポイントのコードをシンプルに保てる
4. 設定情報を dependencies.py
で管理する
アプリケーションの設定(例:環境変数)は、dependencies.py
で管理するのが便利です。
環境変数を利用する依存関係
from pydantic import BaseSettings
class Settings(BaseSettings):
database_url: str
secret_key: str
class Config:
env_file = ".env"
settings = Settings()
使用例
from fastapi import Depends
from app.dependencies import settings
def get_secret_key(settings: Settings = Depends(lambda: settings)):
return settings.secret_key
この方法なら、環境変数を一元管理し、APIエンドポイントでは Depends(get_secret_key)
で呼び出せます。
5. 共通のリクエストヘッダーを dependencies.py
で処理する
APIのクライアントが特定のリクエストヘッダー(例:X-API-Key
)を送ることを期待する場合、それを依存関係として扱うと便利です。
リクエストヘッダーを取得する依存関係
from fastapi import Header, HTTPException
def get_api_key(x_api_key: str = Header(None)):
if x_api_key