スポンサーリンク
概要
最近学び出したFastAPIで、.envファイルを使った設定の読み込む方法のメモ
スポンサーリンク
説明
FastAPIにおける設定
FastAPIではpydanticが提供する型システムやバリデーション機能が魅力の一つ。BaseModelを継承したモデルを使用することでお手軽にこれらの機能が使える。
この機能をアプリケーションの設定として使用できる、pydantic-settingsといった拡張機能が存在する。(pipなどで追加でインストールする必要あり。)
| 
					 1  | 
						pip install pydantic-settings  | 
					
BaseSettingクラス
BaseSettingsクラスを継承することで、BaseModelと同様な機能を使用することができる。
| 
					 1 2 3 4 5 6 7 8  | 
						from fastapi import FastAPI from pydantic_settings import BaseSettings class Settings(BaseSettings):     app_name: str = "Awesome API"     admin_email: str     items_per_user: int = 50  | 
					
このままだと通常のBaseModelと大きい違いはないが、下記のようなmodel_configを定義することで、envファイルから設定を読み込むことができる。
複数指定することで、読み込むファイルの優先度が指定できるので、開発環境や本番環境に合わせて設定をスイッチすることも可能。
pydantic1ではinternal classのConfigを使用した実装方法になっているが、2では下記が推奨方法となるようである。(Config classの方を使うと確か警告が出た気がする。)
| 
					 1 2 3 4 5 6 7 8 9 10  | 
						from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings):     app_name: str = "Awesome API"     admin_email: str     items_per_user: int = 50     # .envファイルから設定を読み込む。複数指定可能。.env.prod => .envの優先度で読み込む     model_config = SettingsConfigDict(env_file=[".env", ".env.prod"])  | 
					
定義されたフィールド名と一致する.envファイルを用意すると、値が上書きされる。
| 
					 1 2 3  | 
						APP_NAME = "Awesome APP" ADMIN_EMAIL = "hoge@hoge.com" ITEMS_PER_USER = 11  | 
					
読み込まれた設定のバリデーションはBaseModelと同様に行うことができる。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17  | 
						from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings):     app_name: str = "Awesome API"     admin_email: str     items_per_user: int = 50     # .envファイルから設定を読み込む。複数指定可能。.env.prod => .envの優先度で読み込む     model_config = SettingsConfigDict(env_file=[".env", ".env.prod"])     # app_nameのバリデーション。設定ファイルからの値が空白、空文字ならエラーとする     @field_validator('app_name', mode='before')     def validate_app_name_value(cls, v) -> str:         if not v.strip():             raise ValueError("app_name must not be empty")         return v  | 
					
なお、使う際には@iru_cacheでデコレートしたメソッドから設定を取り出すことで、キャッシュされて、オブジェクト生成ごとに.envファイルを読み込まなくなる。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						from functools import lru_cache from fastapi import Depends, FastAPI from typing_extensions import Annotated from . import config app = FastAPI() @lru_cache def get_settings():     return config.Settings()  | 
					
参照情報(FastAPIドキュメント)