aditya0103's picture
Initial commit: schemas, extraction engine, dataset prep, 54 passing tests
44c2f50
Raw
History Blame Contribute Delete
2.36 kB
"""Centralized configuration loaded from environment variables."""
from __future__ import annotations
import os
from functools import lru_cache
from dotenv import load_dotenv
from pydantic import BaseModel, Field
load_dotenv()
class Settings(BaseModel):
"""Application settings β€” loaded once at startup."""
# OpenAI
openai_api_key: str = Field(default_factory=lambda: os.getenv("OPENAI_API_KEY", ""))
openai_model: str = Field(default_factory=lambda: os.getenv("OPENAI_MODEL", "gpt-5-nano"))
openai_vision_model: str = Field(
default_factory=lambda: os.getenv("OPENAI_VISION_MODEL", "gpt-5-nano")
)
openai_max_retries: int = Field(
default_factory=lambda: int(os.getenv("OPENAI_MAX_RETRIES", "3"))
)
openai_request_timeout: int = Field(
default_factory=lambda: int(os.getenv("OPENAI_REQUEST_TIMEOUT", "60"))
)
# App
app_env: str = Field(default_factory=lambda: os.getenv("APP_ENV", "development"))
log_level: str = Field(default_factory=lambda: os.getenv("LOG_LEVEL", "INFO"))
api_host: str = Field(default_factory=lambda: os.getenv("API_HOST", "0.0.0.0"))
api_port: int = Field(default_factory=lambda: int(os.getenv("API_PORT", "8000")))
streamlit_port: int = Field(
default_factory=lambda: int(os.getenv("STREAMLIT_PORT", "8501"))
)
# Pricing (gpt-5-nano defaults; override in .env when swapping models)
cost_per_1k_input: float = Field(
default_factory=lambda: float(os.getenv("COST_PER_1K_INPUT_TOKENS", "0.00005"))
)
cost_per_1k_output: float = Field(
default_factory=lambda: float(os.getenv("COST_PER_1K_OUTPUT_TOKENS", "0.00040"))
)
# SEC (v2)
sec_user_agent: str = Field(
default_factory=lambda: os.getenv(
"SEC_USER_AGENT", "ASP Research adityapatel1801@gmail.com"
)
)
def validate_ready(self) -> None:
"""Raise if the app isn't ready to run β€” call at startup."""
if not self.openai_api_key or self.openai_api_key.startswith("sk-your-key"):
raise RuntimeError(
"OPENAI_API_KEY is not set. Copy .env.example to .env and paste your key."
)
@lru_cache(maxsize=1)
def get_settings() -> Settings:
"""Cached singleton β€” call this everywhere instead of instantiating Settings."""
return Settings()