APIエンドポイント
/app/api/main.pyで次のように4つのサブルーターを統合している。
api_router = APIRouter()
api_router.include_router(login.router, tags=["login"])
api_router.include_router(users.router, prefix="/users", tags=["users"])
api_router.include_router(utils.router, prefix="/utils", tags=["utils"])
api_router.include_router(items.router, prefix="/items", tags=["items"])
tags=["login"]
のように、タグ付けすることでSwaggerUI上でタグごとにパスが表示されるようになる。
backend/routers
以下で各ルーターを定義。
/signup
- メールアドレス、パスワード、氏名で新規ユーザー登録をする。
user_create = UserCreate.model_validate(user_in)
として、UserRegister
インスタンスからUserCreate
インスタンスを作る
(UserCreate
のみが持つis_active
属性とis_superuser
属性はデフォルトでそれぞれ、is_active=True
,is_superuser=False
が割り当てられる。 )
設定情報
Pydantic Settingsを使用することでBaseSettingsを継承したクラスの中で環境変数を読み取って、型アノテーションを使用した検証、管理ができる。
環境変数はbackendディレクトリと同階層にある.env
に記述して
Basesettings
クラスを継承したapp/api/core.py
のSettings
クラスで
model_config = SettingsConfigDict(
# Use top level .env file (one level above ./backend/)
env_file="../.env",
env_ignore_empty=True,
extra="ignore",
)
のように環境変数を読み取って、
設定情報を記述している
-
他のファイルでSettingsクラスで定義した設定用変数を使用する手順
- config.pyでsettings = Settings()としてインスタンスを生成
- 設定情報を使用するファイルの中で、from app.core.config import settingsとしてインポート
- 以下のように
settings.(変数名)
という形で記述する。
user_in = UserCreate( email=settings.FIRST_SUPERUSER_EMAIL, password=settings.FIRST_SUPERUSER_PASSWORD, is_superuser=True, user_name=settings.FIRST_SUPERUSER_NAME, )
このようにすることで、Settingsクラスで定義した設定値に簡単にアクセスできる。
参考:
-
https://docs.pydantic.dev/latest/concepts/pydantic_settings/#usage
-
- Pydantic settingsを使用するモチベーションや
SettingsConfigDict
の挙動についてわかりやすく書いてあります
- Pydantic settingsを使用するモチベーションや
https://zenn.dev/nowa0402/articles/47e3edb0e93380
モデル定義
app/models.py
に記述している。
例えば、ORMにSQLAlchemyを使う場合はSQLAlchemyモデルとPydanticモデルの2つを定義する必要がある。
しかし、SQLModelの場合は公式ドキュメント
にあるように、SQLModelモデルはPydanticモデルとSQLAlchemyモデルを兼ねており、1箇所で定義すればよいので冗長性を減らすことができる。
class User(UserBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
hashed_password: str
items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True)
のようにtable=true
とした場合にテーブル定義に使用される。
参考: https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/
依存性注入
app/api/deps.py
には依存性注入に使用する関数を置く
- OAuth2による認証
OAuth2PasswordRequestForm
の実装
https://github.com/fastapi/fastapi/blob/master/fastapi/security/oauth2.py
sequenceDiagram
participant Client as クライアント
participant API as FastAPIサーバー
participant DB as データベース
Client->>API: POST /login/access-token (username, password)
API->>DB: ユーザー情報を照会
alt 認証成功
DB-->>API: ユーザーオブジェクトを返す
API->>API: ユーザーの状態を確認 (is_active)
alt ユーザーが有効
API->>API: トークンの有効期限を設定
API->>API: アクセストークンを生成
API-->>Client: アクセストークンを返す
else ユーザーが無効
API-->>Client: 400エラー (Inactive user)
end
else 認証失敗
DB-->>API: None (ユーザーなし)
API-->>Client: 400エラー (Incorrect email or password)
end