한양과학기술고등학교

에듀테크 프로젝트 대시보드

설정 관리 (pydantic-settings)

BaseSettings .env 환경변수 lru_cache SettingsConfigDict

비밀·환경별 값은 코드에 넣지 않습니다. 환경변수/.env 에서 읽고 타입 검증까지.

1. 설치와 정의

pip install pydantic-settings
app/config.py
from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")

    app_name: str = "school-api"
    debug: bool = False
    database_url: str                       # 필수 (없으면 시작 시 에러)
    secret_key: str
    access_token_expire_minutes: int = 30
    cors_origins: list[str] = []

2. .env 파일

.env (git 에 커밋하지 말 것)
DEBUG=true
DATABASE_URL=postgresql+psycopg://school:secret@localhost:5432/school
SECRET_KEY=change-me-to-a-long-random-string
ACCESS_TOKEN_EXPIRE_MINUTES=60
CORS_ORIGINS=["https://offset0xf.com"]

환경변수 이름은 대소문자 무시. DATABASE_URL → database_url.

3. 캐시된 싱글턴으로 주입

from functools import lru_cache
from fastapi import Depends
from typing import Annotated

@lru_cache
def get_settings() -> Settings:
    return Settings()

SettingsDep = Annotated[Settings, Depends(get_settings)]

@app.get("/info")
def info(settings: SettingsDep):
    return {"app": settings.app_name, "debug": settings.debug}

4. 테스트에서 오버라이드

def get_settings_override():
    return Settings(database_url="sqlite://", secret_key="test")

app.dependency_overrides[get_settings] = get_settings_override

5. systemd 에서 환경변수 주입

# /etc/systemd/system/fastapi-school.service
[Service]
EnvironmentFile=/home/ubuntu/offset0xf/school/.env
# 또는
Environment="DATABASE_URL=postgresql+psycopg://..."
"마이그레이션 없는 스키마 변경은 사고의 시작이다"