kr4phy's picture
Sync from GitHub
cff6ac7
Raw
History Blame Contribute Delete
4.37 kB
"""
μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„€μ • λͺ¨λ“ˆ.
ν™˜κ²½ λ³€μˆ˜(.env)λ₯Ό pydantic-settings 둜 λ‘œλ“œν•˜λ©°,
λͺ¨λ“  섀정은 이 λͺ¨λ“ˆμ˜ ``get_settings()`` ν•¨μˆ˜λ₯Ό 톡해 μ ‘κ·Όν•©λ‹ˆλ‹€.
"""
from __future__ import annotations
from functools import lru_cache
from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""μ „μ—­ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„€μ •."""
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
extra="ignore",
)
# ── 곡곡데이터포털 (data.go.kr) ─────────────────────────
data_go_kr_api_key: str = Field(
default="",
description="data.go.kr μ„œλΉ„μŠ€ 인증킀",
)
data_go_kr_base_url: str = Field(
default="https://open.neis.go.kr/hub",
description="data.go.kr NEIS Open API κΈ°λ³Έ URL",
)
# ── κ΅μœ‘λ°μ΄ν„° ν™œμš©Β·μ§€μ› μ„œλΉ„μŠ€ (data.edmgr.kr) ──────────
edmgr_api_key: str = Field(
default="",
description="data.edmgr.kr μ„œλΉ„μŠ€ 인증킀",
)
edmgr_base_url: str = Field(
default="https://open.neis.go.kr/hub",
description="NEIS 학ꡐ기본정보 API κΈ°λ³Έ URL",
)
# ── ν–‰μ •μ•ˆμ „λΆ€ 주민등둝 인ꡬ톡계 ─────────────────────────
mois_api_key: str = Field(
default="",
description="ν–‰μ•ˆλΆ€ 주민등둝 인ꡬ톡계 μ„œλΉ„μŠ€ 인증킀",
)
mois_base_url: str = Field(
default="https://jumin.mois.go.kr/ageStatMonth.do",
description="ν–‰μ•ˆλΆ€ 인ꡬ톡계 API URL",
)
# ── Hugging Face ─────────────────────────────────────────
huggingface_hub_token: str = Field(
default="",
description="Hugging Face Hub μ•‘μ„ΈμŠ€ 토큰",
)
granite_model_id: str = Field(
default="ibm-granite/granite-timeseries-ttm-r2",
description="Granite TTM λͺ¨λΈ μ‹λ³„μž",
)
# ── μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ─────────────────────────────────────────
app_env: str = Field(default="development")
log_level: str = Field(default="INFO")
api_host: str = Field(default="0.0.0.0")
api_port: int = Field(default=8000, ge=1, le=65535)
api_workers: int = Field(default=1, ge=1)
# ── μΊμ‹œ ─────────────────────────────────────────────────
redis_url: str = Field(default="")
cache_ttl_seconds: int = Field(default=3600, ge=0)
# ── 데이터 μˆ˜μ§‘ ───────────────────────────────────────────
ingest_page_size: int = Field(default=1000, ge=1, le=5000)
ingest_max_retries: int = Field(default=3, ge=0, le=10)
ingest_retry_delay: float = Field(default=2.0, ge=0.0)
http_timeout: int = Field(default=30, ge=5, le=120)
# ── 예츑 ─────────────────────────────────────────────────
prediction_context_length: int = Field(default=60, ge=12, le=120)
prediction_horizon_months: int = Field(default=60, ge=12, le=120)
@field_validator("log_level")
@classmethod
def _validate_log_level(cls, v: str) -> str:
allowed = {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}
upper = v.upper()
if upper not in allowed:
raise ValueError(f"log_level 은 {allowed} 쀑 ν•˜λ‚˜μ—¬μ•Ό ν•©λ‹ˆλ‹€.")
return upper
@field_validator("app_env")
@classmethod
def _validate_app_env(cls, v: str) -> str:
allowed = {"development", "production", "test"}
lower = v.lower()
if lower not in allowed:
raise ValueError(f"app_env λŠ” {allowed} 쀑 ν•˜λ‚˜μ—¬μ•Ό ν•©λ‹ˆλ‹€.")
return lower
@lru_cache(maxsize=1)
def get_settings() -> Settings:
"""μ„€μ • 싱글톀 λ°˜ν™˜ (졜초 호좜 μ‹œ .env νŒŒμΌμ„ 읽음)."""
return Settings()