C.W.K.
Stream
Lesson 07 of 08 · published

애플리케이션 config — pydantic, dataclass, env override

~10 min · yaml, config, pydantic, dataclass

Level 0평문
0 XP0/64 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

앱의 YAML, 위에 env var

현대 service 가 보통 config 를 layer: YAML 파일이 기본값 보유, 환경 변수가 배포별 override, runtime 인자가 호출별 override. 패턴: YAML 을 강타입 config 객체로 파싱 후 env var 가 이름으로 필드 패치하게.

Pydantic Settings (Python)

Pydantic V2 가 pydantic_settings 출시: BaseSettings subclass 정의, YAML 파일 (custom source 통해) 가리키면, env var 가 자동으로 필드 override. parse-time 타입 에러가 배포 전 오타 잡음.

'설정당 한 타입' 원칙

타입 미리 정의: port: int = 8000, log_level: Literal["debug","info","warn","error"] = "info". 파서가 안 맞는 값 거부. JSON Schema 와 같은 아이디어, 언어 타입 시스템에서.

원칙: raw YAML 을 dict 로 읽고 string key 로 들어가지 마 (config["server"]["port"]). 잘못된 key, 누락된 key, 잘못된 타입 — 다 silent runtime crash. 강타입 config 객체가 그걸 parse-time 에러로 변환.

Code

Pydantic Settings + YAML·python
from pathlib import Path
from typing import Literal
import yaml
from pydantic_settings import BaseSettings, PydanticBaseSettingsSource

class YamlConfigSource(PydanticBaseSettingsSource):
    def get_field_value(self, *args, **kwargs):
        return None  # __call__ 에 위임
    def __call__(self):
        path = Path('config.yaml')
        if path.exists():
            return yaml.safe_load(path.read_text()) or {}
        return {}

class Settings(BaseSettings):
    port: int = 8000
    host: str = 'localhost'
    log_level: Literal['debug', 'info', 'warn', 'error'] = 'info'
    database_url: str

    @classmethod
    def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings):
        return (init_settings, env_settings, YamlConfigSource(settings_cls), dotenv_settings, file_secret_settings)

settings = Settings()
print(settings.port)  # YAML 에서 8000, 또는 PORT env var 로 override
config.yaml·yaml
port: 8000
host: 0.0.0.0
log_level: info
database_url: postgresql://postgres:dev@localhost/pippa
Runtime 환경 override·bash
# 한 필드 override — env var 가 YAML 이김
LOG_LEVEL=debug PORT=9000 python -m myapp

# Dockerfile / k8s ConfigMap 에서
env:
  - name: LOG_LEVEL
    value: debug
  - name: DATABASE_URL
    valueFrom:
      secretKeyRef:
        name: pippa-secrets
        key: database-url

External links

Exercise

config 읽는 작은 앱 골라. 현재 yaml.safe_load + dict 접근 이라면 강타입 config 객체 (pydantic, attrs, dataclass + cattrs) 로 포팅. 누락된 필드나 잘못된 타입 필드 읽어보고 boot 에서 parse 실패 — 그게 이득.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.