Files
openrouter-watcher/src/openrouter_monitor/config.py
Luca Sacchi Ricciardi 3ae5d736ce feat(tasks): T55-T58 implement background tasks for OpenRouter sync
- T55: Setup APScheduler with AsyncIOScheduler and @scheduled_job decorator
- T56: Implement hourly usage stats sync from OpenRouter API
- T57: Implement daily API key validation job
- T58: Implement weekly cleanup job for old usage stats
- Add usage_stats_retention_days config option
- Integrate scheduler with FastAPI lifespan events
- Add 26 unit tests for scheduler, sync, and cleanup tasks
- Add apscheduler to requirements.txt

The background tasks now automatically:
- Sync usage stats every hour from OpenRouter
- Validate API keys daily at 2 AM UTC
- Clean up old data weekly on Sunday at 3 AM UTC
2026-04-07 17:41:24 +02:00

112 lines
3.1 KiB
Python

"""Configuration management using Pydantic Settings.
This module provides centralized configuration management for the
OpenRouter API Key Monitor application.
"""
from functools import lru_cache
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import Field
class Settings(BaseSettings):
"""Application settings loaded from environment variables.
Required environment variables:
- SECRET_KEY: JWT signing key (min 32 chars)
- ENCRYPTION_KEY: AES-256 encryption key (32 bytes)
Optional environment variables with defaults:
- DATABASE_URL: SQLite database path
- OPENROUTER_API_URL: OpenRouter API base URL
- SYNC_INTERVAL_MINUTES: Background sync interval
- MAX_API_KEYS_PER_USER: API key limit per user
- RATE_LIMIT_REQUESTS: API rate limit
- RATE_LIMIT_WINDOW: Rate limit window (seconds)
- JWT_EXPIRATION_HOURS: JWT token lifetime
- DEBUG: Debug mode flag
- LOG_LEVEL: Logging level
"""
# Database
database_url: str = Field(
default="sqlite:///./data/app.db",
description="SQLite database URL"
)
# Security - REQUIRED
secret_key: str = Field(
description="JWT signing key (min 32 characters)"
)
encryption_key: str = Field(
description="AES-256 encryption key (32 bytes)"
)
jwt_expiration_hours: int = Field(
default=24,
description="JWT token expiration in hours"
)
# OpenRouter Integration
openrouter_api_url: str = Field(
default="https://openrouter.ai/api/v1",
description="OpenRouter API base URL"
)
# Task scheduling
sync_interval_minutes: int = Field(
default=60,
description="Background sync interval in minutes"
)
usage_stats_retention_days: int = Field(
default=365,
description="Retention period for usage stats in days"
)
# Limits
max_api_keys_per_user: int = Field(
default=10,
description="Maximum API keys per user"
)
max_api_tokens_per_user: int = Field(
default=5,
description="Maximum API tokens per user"
)
rate_limit_requests: int = Field(
default=100,
description="API rate limit requests"
)
rate_limit_window: int = Field(
default=3600,
description="Rate limit window in seconds"
)
# App settings
debug: bool = Field(
default=False,
description="Debug mode"
)
log_level: str = Field(
default="INFO",
description="Logging level"
)
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False
)
@lru_cache()
def get_settings() -> Settings:
"""Get cached settings instance.
Returns:
Settings: Application settings instance
Example:
>>> from openrouter_monitor.config import get_settings
>>> settings = get_settings()
>>> print(settings.database_url)
"""
return Settings()