Spaces:
Running
on
Zero
Running
on
Zero
| """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" | |
| ) | |
| # 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() | |