Pydantic BaseSettings 攻略ガイド
Why BaseSettings?
- 環境依存値を型安全に管理し、設定ミスをゼロに。
- ローカル → CI → ステージング → 本番 まで同一コードを使い回し。
- Secrets・Kubernetes・リモート設定サービス との統合を最小コードで実現。
1. インストール & バージョンガイド
-
現行最新版 (v2.6 〜)
pip install "pydantic[dotenv]~=2.6"
-
dotenv
extras を入れると.env
自動読込が可能。 - 依存: Python 3.8+
-
-
レガシー (v1.x)
pip install "pydantic<2"
- 新規プロジェクトなら v2 を強く推奨。
バージョン判定ワンライナー
import pydantic, sys
print(pydantic.version.VERSION, sys.version)
v1 → v2 で得られる主なメリット
- 40〜50% 高速化(新パースエンジン)
-
バリデータがデコレータ一発
@field_validator
- 型エラー時のメッセージがより詳細 & 多言語化
- settings_customise_sources によるカスタムソース統合が簡潔
2. 基本の使い方 ― 5 分で “Hello, Settings”
# settings.py
from pydantic import BaseSettings
class Settings(BaseSettings):
app_name: str = "MyApp"
port: int
debug: bool = False
model_config = {
"env_prefix": "APP_", # 全フィールド共通プレフィックス
"env_file": ".env", # カレントの .env を読込
"env_file_encoding": "utf-8",
}
settings = Settings() # ⚡️ 一行で解決
.env
サンプル
APP_PORT=8000
APP_DEBUG=true
ここだけは覚えて:読み込み優先順位
- 直接
Settings(port=9999)
など コード引数 -
環境変数(例:
export APP_PORT=8888
) - .env ファイル
- デフォルト値(クラス宣言内)
インフラ→CI→ローカル の上書き戦略がシンプル!
3. よく使うテクニック集
3‑1. シングルトン化で多重ロード防止
from functools import lru_cache
@lru_cache
def get_settings():
return Settings()
→ FastAPI では Depends(get_settings)
で DI。
3‑2. プレフィックス & エイリアス
from pydantic import Field
class API(BaseSettings):
url: str = Field(alias="SERVICE_URL")
timeout: int = Field(default=5, alias="SERVICE_TIMEOUT")
→ 外部サービス名変更時に Python コードは無改修。
3‑3. Secret 値 & マスキング
from pydantic import SecretStr
class Creds(BaseSettings):
password: SecretStr
-
print(creds)
→password=SecretStr('**********')
-
creds.password.get_secret_value()
で生値取得。
3‑4. 型変換 Tips
-
bool
は"true" "True" "1"
など case-insensitive でTrue
。 -
list[int]
は"1,2,3"
または JSON 文字列[1, 2, 3]
を受容。 -
Path
型は OS パスセパレータを自動調整(Windows↔Unix)。
4. 応用:マルチ環境 & カスタムソース
4‑1. 環境別 .env を自動切替
import os
class EnvSettings(BaseSettings):
env: str = os.getenv("ENV", "local")
model_config = {"env_file": f".env.{env}"}
-
ENV=prod python main.py
で.env.prod
を読込。 - CI では
.env.ci
を用意するとセキュア。
4‑2. YAML + HTTP + env の 3 層構成例
from pathlib import Path
import yaml, requests
from pydantic import BaseSettings
def yaml_source(_: BaseSettings):
yml = Path("config.yaml")
return yaml.safe_load(yml.read_text()) if yml.exists() else {}
def http_source(_: BaseSettings):
r = requests.get("http://config-svc.local/config")
return r.json() if r.ok else {}
class Cfg(BaseSettings):
feature_flag: bool = False
user_quota: int = 100
model_config = {
"settings_customise_sources": lambda cls, _: (
http_source, yaml_source, *BaseSettings.settings_customise_sources()
)
}
- HTTP > YAML > env > .env > default の優先度が実現。
4‑3. 完全ネストモデル
class PG(BaseSettings):
host: str
port: int = 5432
db: str
class Redis(BaseSettings):
url: str
class Global(BaseSettings):
pg: PG
redis: Redis
- 必要な環境変数は
PG_HOST
,PG_PORT
,REDIS_URL
等。 - .env が肥大化したらファイル分割 or Prefix で整理。
5. 運用:テスト・リロード・フレームワーク統合
5‑1. テストでの環境変数上書き
import pytest
from settings import Settings
def test_debug(monkeypatch):
monkeypatch.setenv("APP_DEBUG", "true")
assert Settings().debug is True
-
monkeypatch
はテスト終了後に自動リセット。
5‑2. 設定ホットリロード(watchdog 使用例)
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
class ReloadHandler(FileSystemEventHandler):
def on_modified(self, event):
if event.src_path.endswith(".env"):
Settings.model_reset() # v2 のみ
print("🔄 Settings reloaded")
5‑3. フレームワーク接続例
-
FastAPI:
settings = Settings(); app = FastAPI()
→ 依存注入でシングルトン共有。 -
Celery: Worker 起動スクリプト内で
os.environ.update(Settings().model_dump())
。 -
Django:
settings.py
内でfrom .settings_obj import Settings
。DjangoConf を置換可能。
6. 移行 & バージョン差分チェックリスト
- Config → model_config に置換。
- @validator → @field_validator へリネーム。
- json() / dict() → model_dump_json() / model_dump()。
- **allow_mutation=False → model_config = {"frozen": True}`。
- parse_obj_as → pydantic.TypeAdapter().validate_python(...)。
-
settings_customise_sources は新 API 名。旧
customise_sources
は削除。
🚩 まずはテストを用意 →
pip install "pydantic[dotenv]>=2" --upgrade
→ エラーを上から潰す。
7. よくある落とし穴と対策
-
インスタンスを複数生成 → 毎回ファイル I/O → 遅延。
⇒@lru_cache
を付けて シングルトン 化。 -
bool 変換の罠 →
"false" "0" "no"
以外のスペルは全部True
扱い。
⇒.env
では 小文字 true/false を統一。 -
巨大ネスト → 環境変数名が長大化。
⇒.env
を複数ファイルに分割 or YAML/HTTP を併用。 -
Secret の誤露出 →
print(settings)
がパスワードを表示。
⇒SecretStr
を必ず使う & 発行先ログを確認。 -
文字エンコーディング → Windows の CP932 で
.env
が文字化け。
⇒model_config["env_file_encoding"] = "utf-8"
を明示。
8. スニペット集 & リンク
8‑1. AWS 認証キーの最小定義
class AWS(BaseSettings):
access_key: str
secret_key: SecretStr
region: str = "ap-northeast-1"
model_config = {"env_prefix": "AWS_"}
8‑2. 実行時 CPU コア数でデフォルト設定
import os, multiprocessing
class Perf(BaseSettings):
workers: int = multiprocessing.cpu_count() * 2 + 1
8‑3. Slack Webhook + Proxy 設定
class Slack(BaseSettings):
webhook_url: str = Field(..., alias="SLACK_WEBHOOK")
proxy: str | None = Field(None, alias="HTTPS_PROXY")
8‑4. 公式 & 実例ドキュメント
- Pydantic Settings: https://docs.pydantic.dev/latest/usage/pydantic_settings/
- FastAPI Settings Example: https://fastapi.tiangolo.com/advanced/settings/
- Pydantic GitHub Discussions: 最新パターンをキャッチアップ。
🏁 まとめ
“設定はコードの一部” — BaseSettings で “人間が触る領域” を統制し、アプリ本体は “型保証された設定オブジェクト” に依存するだけ。これが 運用・開発・セキュリティ をラクにする最短ルート!