"""Configuration module for Portfolio Intelligence Platform. Loads environment variables and provides configuration settings. """ import os from typing import Optional from pydantic import Field, ConfigDict from pydantic_settings import BaseSettings class Settings(BaseSettings): """Application settings loaded from environment variables. Attributes: anthropic_api_key: Anthropic API key for Claude anthropic_model: Anthropic model ID (default: claude-sonnet-4-5-20250929) supabase_url: Supabase project URL supabase_key: Supabase anon key fmp_api_key: Financial Modeling Prep API key fred_api_key: FRED (Federal Reserve Economic Data) API key upstash_redis_url: Upstash Redis REST URL for caching upstash_redis_token: Upstash Redis REST token cache_enabled: Enable/disable caching globally cache_fallback_enabled: Enable in-memory fallback when Redis unavailable environment: Application environment (development/production) log_level: Logging level """ # AI/LLM Configuration anthropic_api_key: str = Field( default="", validation_alias="ANTHROPIC_API_KEY" ) anthropic_model: str = Field( default="claude-sonnet-4-5-20250929", validation_alias="ANTHROPIC_MODEL" ) # Database Configuration supabase_url: Optional[str] = Field( default=None, validation_alias="SUPABASE_URL" ) supabase_key: Optional[str] = Field( default=None, validation_alias="SUPABASE_KEY" ) supabase_service_role_key: Optional[str] = Field( default=None, validation_alias="SUPABASE_SERVICE_ROLE_KEY" ) # Financial Data APIs fmp_api_key: Optional[str] = Field( default=None, validation_alias="FMP_API_KEY" ) fred_api_key: Optional[str] = Field( default=None, validation_alias="FRED_API_KEY" ) finnhub_api_key: Optional[str] = Field( default=None, validation_alias="FINNHUB_API_KEY" ) alpaca_api_key: Optional[str] = Field( default=None, validation_alias="ALPACA_API_KEY" ) alpaca_secret_key: Optional[str] = Field( default=None, validation_alias="ALPACA_SECRET_KEY" ) # ElevenLabs TTS Configuration elevenlabs_api_key: Optional[str] = Field( default=None, validation_alias="ELEVENLABS_API_KEY", description="ElevenLabs API key for text-to-speech generation" ) elevenlabs_enabled: bool = Field( default=True, validation_alias="ELEVENLABS_ENABLED", description="Enable/disable audio generation features" ) # Application Settings environment: str = Field( default="development", validation_alias="ENVIRONMENT" ) log_level: str = Field( default="INFO", validation_alias="LOG_LEVEL" ) app_url: str = Field( default="http://localhost:7860", validation_alias="APP_URL", description="Public URL where the application is accessible" ) # Rate Limiting Settings redis_url: Optional[str] = Field( default=None, validation_alias="REDIS_URL" ) rate_limit_enabled: bool = Field( default=True, validation_alias="RATE_LIMIT_ENABLED" ) # Rate limit tiers (fixed window - resets daily at midnight UTC) # Anonymous (Demo Mode): 1 request per day rate_limit_anonymous_capacity: int = Field( default=1, validation_alias="RATE_LIMIT_ANONYMOUS_CAPACITY", description="Number of requests allowed per day for anonymous users" ) rate_limit_anonymous_refill_rate: float = Field( default=1.0 / 86400.0, # DEPRECATED: Not used with fixed window validation_alias="RATE_LIMIT_ANONYMOUS_REFILL_RATE" ) # Authenticated: 3 requests per day rate_limit_authenticated_capacity: int = Field( default=3, validation_alias="RATE_LIMIT_AUTHENTICATED_CAPACITY", description="Number of requests allowed per day for authenticated users" ) rate_limit_authenticated_refill_rate: float = Field( default=1.0 / 86400.0, # DEPRECATED: Not used with fixed window validation_alias="RATE_LIMIT_AUTHENTICATED_REFILL_RATE" ) # Premium: 200 requests capacity, refills at 2.0 requests/second (2 every second) rate_limit_premium_capacity: int = Field( default=200, validation_alias="RATE_LIMIT_PREMIUM_CAPACITY" ) rate_limit_premium_refill_rate: float = Field( default=2.0, validation_alias="RATE_LIMIT_PREMIUM_REFILL_RATE" ) # Market Data Provider Configuration market_data_provider: str = Field( default="yfinance", validation_alias="MARKET_DATA_PROVIDER" ) fmp_tier: str = Field( default="free", validation_alias="FMP_TIER" ) # Caching Configuration (Upstash Redis) upstash_redis_url: Optional[str] = Field( default=None, validation_alias="UPSTASH_REDIS_URL" ) upstash_redis_token: Optional[str] = Field( default=None, validation_alias="UPSTASH_REDIS_TOKEN" ) cache_enabled: bool = Field( default=True, validation_alias="CACHE_ENABLED" ) cache_fallback_enabled: bool = Field( default=True, validation_alias="CACHE_FALLBACK_ENABLED" ) cache_fallback_max_size: int = Field( default=1000, validation_alias="CACHE_FALLBACK_MAX_SIZE" ) # Cache TTLs for different data types cache_ttl_quotes: int = Field( default=60, validation_alias="CACHE_TTL_QUOTES" ) cache_ttl_historical: int = Field( default=14400, validation_alias="CACHE_TTL_HISTORICAL" ) cache_ttl_fundamentals: int = Field( default=86400, validation_alias="CACHE_TTL_FUNDAMENTALS" ) cache_ttl_ratios: int = Field( default=604800, validation_alias="CACHE_TTL_RATIOS" ) # Sentry Error Monitoring sentry_dsn: Optional[str] = Field( default=None, validation_alias="SENTRY_DSN" ) sentry_tier: str = Field( default="free", validation_alias="SENTRY_TIER" ) sentry_release: Optional[str] = Field( default=None, validation_alias="SENTRY_RELEASE" ) sentry_debug: bool = Field( default=False, validation_alias="SENTRY_DEBUG" ) model_config = ConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, ) # Global settings instance settings = Settings()