SPB Git

spb/findata

Public
2.7 KB · 73 lines python
1from __future__ import annotations23from functools import lru_cache4from pathlib import Path56from pydantic import Field, SecretStr7from pydantic_settings import BaseSettings, SettingsConfigDict8910class Settings(BaseSettings):11    """Runtime settings. Secrets are `SecretStr` so that `repr()`/logging never prints them."""1213    model_config = SettingsConfigDict(env_prefix="FINDATA_", env_file=".env", env_file_encoding="utf-8", extra="ignore")1415    env: str = "development"16    root: Path = Field(default_factory=lambda: Path.cwd())17    lake: Path = Field(default_factory=lambda: Path.cwd() / "data" / "lake")18    database_url: SecretStr = SecretStr("postgresql://findata:findata-local@127.0.0.1:5432/findata")19    bind_host: str = "127.0.0.1"20    bind_port: int = 860021    public_url: str = "http://127.0.0.1:8600"22    secret_key: SecretStr = SecretStr("dev-only-change-me-dev-only-change-me")23    lake_soft_limit_gb: float = 250.024    lake_hard_min_free_gb: float = 60.025    backup_target: str = ""26    # vendor + optional providers (no FINDATA_ prefix: read explicitly)27    frd_userid: SecretStr = Field(default=SecretStr(""), validation_alias="FRD_USERID")28    sec_edgar_user_agent: str = Field(default="", validation_alias="SEC_EDGAR_USER_AGENT")29    anthropic_api_key: SecretStr = Field(default=SecretStr(""), validation_alias="ANTHROPIC_API_KEY")30    openai_api_key: SecretStr = Field(default=SecretStr(""), validation_alias="OPENAI_API_KEY")31    # web static bundle32    web_dist: Path | None = None33    # rate limiting defaults (per API key / session)34    rate_limit_per_minute: int = 60035    query_timeout_seconds: int = 3036    query_max_rows: int = 100_00037    bars_max_rows_json: int = 50_00038    export_ttl_hours: int = 723940    @property41    def is_production(self) -> bool:42        return self.env == "production"4344    @property45    def raw_dir(self) -> Path:46        return self.lake / "raw"4748    @property49    def curated_dir(self) -> Path:50        return self.lake / "curated"5152    @property53    def exports_dir(self) -> Path:54        return self.lake / "exports"5556    @property57    def tmp_dir(self) -> Path:58        return self.lake / "_tmp"5960    def secret_values(self) -> list[str]:61        """Every secret string that must never appear in logs or error messages."""62        vals = [self.frd_userid.get_secret_value(), self.anthropic_api_key.get_secret_value(),63                self.openai_api_key.get_secret_value()]64        pw = self.database_url.get_secret_value()65        if "@" in pw and ":" in pw.split("@")[0]:66            vals.append(pw.split("@")[0].rsplit(":", 1)[-1])67        return [v for v in vals if v and len(v) >= 6]686970@lru_cache71def get_settings() -> Settings:72    return Settings()73
Files · 8aa539b79849fb28991011546f6e2c19166d7f01
Menu

Theme