You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.0 KiB
Python
81 lines
2.0 KiB
Python
"""Application configuration via pydantic-settings + YAML merge."""
|
|
from __future__ import annotations
|
|
|
|
import functools
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import yaml
|
|
from pydantic import field_validator
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
def _load_yaml(path: str | Path) -> dict[str, Any]:
|
|
p = Path(path)
|
|
if p.exists():
|
|
with open(p) as f:
|
|
return yaml.safe_load(f) or {}
|
|
return {}
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(
|
|
env_file=".env",
|
|
env_file_encoding="utf-8",
|
|
case_sensitive=False,
|
|
extra="ignore",
|
|
)
|
|
|
|
app_env: str = "dev"
|
|
|
|
# Stock Oracle
|
|
stock_oracle_url: str = "http://localhost:18001"
|
|
stock_oracle_timeout: int = 30
|
|
|
|
# Database
|
|
postgres_dsn: str = "postgresql+asyncpg://acef:acef@localhost:5432/acef"
|
|
|
|
# File storage
|
|
data_root: str = "./data"
|
|
|
|
# Logging
|
|
log_level: str = "INFO"
|
|
|
|
# LLM
|
|
openai_api_key: str = "sk-placeholder"
|
|
llm_enabled: bool = False
|
|
|
|
# App YAML overrides (loaded separately)
|
|
_app_config: dict[str, Any] = {}
|
|
|
|
@field_validator("log_level")
|
|
@classmethod
|
|
def normalize_log_level(cls, v: str) -> str:
|
|
return v.upper()
|
|
|
|
@property
|
|
def exhibit_cache_dir(self) -> Path:
|
|
return Path(self.data_root) / "cache" / "exhibits"
|
|
|
|
@property
|
|
def parquet_dir(self) -> Path:
|
|
return Path(self.data_root) / "parquet"
|
|
|
|
def get_app_config(self) -> dict[str, Any]:
|
|
if not self._app_config:
|
|
object.__setattr__(self, "_app_config", _load_yaml("configs/app.yaml"))
|
|
return self._app_config
|
|
|
|
def get_symbols(self) -> list[str]:
|
|
cfg = _load_yaml("configs/symbols.yaml")
|
|
return cfg.get("symbols", [])
|
|
|
|
def get_fred_series(self) -> list[dict[str, Any]]:
|
|
cfg = _load_yaml("configs/fred_series.yaml")
|
|
return cfg.get("series", [])
|
|
|
|
|
|
@functools.lru_cache(maxsize=1)
|
|
def get_settings() -> Settings:
|
|
return Settings()
|