monitor displaying error text
Photo by Pixabay on Pexels.com

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

投稿者 greeden

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)