Source code for trailpack.pyst.api.config

from dataclasses import dataclass
from typing import Optional
import os
from pathlib import Path

# Load .env file if it exists
try:
    from dotenv import load_dotenv
    # Look for .env file in project root
[docs] env_path = Path(__file__).parent.parent.parent.parent / ".env"
if env_path.exists(): load_dotenv(env_path) except ImportError: pass # python-dotenv not installed try: import streamlit as st except ImportError: # Streamlit not available outside the app
[docs] st = None
@dataclass
[docs] class PystConfig: """Centralized PyST configuration"""
[docs] host: str
[docs] auth_token: Optional[str] = None
[docs] timeout: int = 30
@classmethod
[docs] def from_env(cls): """Load configuration from Streamlit secrets with env fallback""" secret_host: Optional[str] = None secret_auth_token: Optional[str] = None if st is not None: try: secrets = st.secrets except Exception: secrets = None if secrets is not None: try: secret_host = secrets["PYST_HOST"] except Exception: secret_host = None try: secret_auth_token = secrets["PYST_AUTH_TOKEN"] except Exception: secret_auth_token = None return cls( host=secret_host or os.getenv("PYST_HOST", "http://localhost:8000"), auth_token=secret_auth_token or os.getenv("PYST_AUTH_TOKEN"), timeout=int(os.getenv("PYST_TIMEOUT", "30")) )
# Global config instance - use lazy loading to ensure secrets are available
[docs] _config: Optional[PystConfig] = None
[docs] def get_config() -> PystConfig: """Get or create the global config instance. Uses lazy loading to ensure Streamlit secrets are available when accessed. """ global _config if _config is None: _config = PystConfig.from_env() return _config
# Backwards compatibility - config property that loads lazily
[docs] class _ConfigProxy: """Proxy object that loads config on first access.""" def __getattr__(self, name): return getattr(get_config(), name)
[docs] config = _ConfigProxy()