310 lines
11 KiB
Python
310 lines
11 KiB
Python
"""
|
|
Centralized configuration management for WiFi-DensePose API
|
|
"""
|
|
|
|
import os
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Dict, Any, Optional, List
|
|
from functools import lru_cache
|
|
|
|
from src.config.settings import Settings, get_settings
|
|
from src.config.domains import DomainConfig, get_domain_config
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ConfigManager:
|
|
"""Centralized configuration manager."""
|
|
|
|
def __init__(self):
|
|
self._settings: Optional[Settings] = None
|
|
self._domain_config: Optional[DomainConfig] = None
|
|
self._environment_overrides: Dict[str, Any] = {}
|
|
|
|
@property
|
|
def settings(self) -> Settings:
|
|
"""Get application settings."""
|
|
if self._settings is None:
|
|
self._settings = get_settings()
|
|
return self._settings
|
|
|
|
@property
|
|
def domain_config(self) -> DomainConfig:
|
|
"""Get domain configuration."""
|
|
if self._domain_config is None:
|
|
self._domain_config = get_domain_config()
|
|
return self._domain_config
|
|
|
|
def reload_settings(self) -> Settings:
|
|
"""Reload settings from environment."""
|
|
self._settings = None
|
|
return self.settings
|
|
|
|
def reload_domain_config(self) -> DomainConfig:
|
|
"""Reload domain configuration."""
|
|
self._domain_config = None
|
|
return self.domain_config
|
|
|
|
def set_environment_override(self, key: str, value: Any):
|
|
"""Set environment variable override."""
|
|
self._environment_overrides[key] = value
|
|
os.environ[key] = str(value)
|
|
|
|
def get_environment_override(self, key: str, default: Any = None) -> Any:
|
|
"""Get environment variable override."""
|
|
return self._environment_overrides.get(key, os.environ.get(key, default))
|
|
|
|
def clear_environment_overrides(self):
|
|
"""Clear all environment overrides."""
|
|
for key in self._environment_overrides:
|
|
if key in os.environ:
|
|
del os.environ[key]
|
|
self._environment_overrides.clear()
|
|
|
|
def get_database_config(self) -> Dict[str, Any]:
|
|
"""Get database configuration."""
|
|
settings = self.settings
|
|
|
|
config = {
|
|
"url": settings.get_database_url(),
|
|
"pool_size": settings.database_pool_size,
|
|
"max_overflow": settings.database_max_overflow,
|
|
"echo": settings.is_development and settings.debug,
|
|
"pool_pre_ping": True,
|
|
"pool_recycle": 3600, # 1 hour
|
|
}
|
|
|
|
return config
|
|
|
|
def get_redis_config(self) -> Optional[Dict[str, Any]]:
|
|
"""Get Redis configuration."""
|
|
settings = self.settings
|
|
redis_url = settings.get_redis_url()
|
|
|
|
if not redis_url:
|
|
return None
|
|
|
|
config = {
|
|
"url": redis_url,
|
|
"password": settings.redis_password,
|
|
"db": settings.redis_db,
|
|
"decode_responses": True,
|
|
"socket_connect_timeout": 5,
|
|
"socket_timeout": 5,
|
|
"retry_on_timeout": True,
|
|
"health_check_interval": 30,
|
|
}
|
|
|
|
return config
|
|
|
|
def get_logging_config(self) -> Dict[str, Any]:
|
|
"""Get logging configuration."""
|
|
return self.settings.get_logging_config()
|
|
|
|
def get_cors_config(self) -> Dict[str, Any]:
|
|
"""Get CORS configuration."""
|
|
return self.settings.get_cors_config()
|
|
|
|
def get_security_config(self) -> Dict[str, Any]:
|
|
"""Get security configuration."""
|
|
settings = self.settings
|
|
|
|
config = {
|
|
"secret_key": settings.secret_key,
|
|
"jwt_algorithm": settings.jwt_algorithm,
|
|
"jwt_expire_hours": settings.jwt_expire_hours,
|
|
"allowed_hosts": settings.allowed_hosts,
|
|
"enable_authentication": settings.enable_authentication,
|
|
}
|
|
|
|
return config
|
|
|
|
def get_hardware_config(self) -> Dict[str, Any]:
|
|
"""Get hardware configuration."""
|
|
settings = self.settings
|
|
domain_config = self.domain_config
|
|
|
|
config = {
|
|
"wifi_interface": settings.wifi_interface,
|
|
"csi_buffer_size": settings.csi_buffer_size,
|
|
"polling_interval": settings.hardware_polling_interval,
|
|
"mock_hardware": settings.mock_hardware,
|
|
"routers": [router.dict() for router in domain_config.routers],
|
|
}
|
|
|
|
return config
|
|
|
|
def get_pose_config(self) -> Dict[str, Any]:
|
|
"""Get pose estimation configuration."""
|
|
settings = self.settings
|
|
domain_config = self.domain_config
|
|
|
|
config = {
|
|
"model_path": settings.pose_model_path,
|
|
"confidence_threshold": settings.pose_confidence_threshold,
|
|
"batch_size": settings.pose_processing_batch_size,
|
|
"max_persons": settings.pose_max_persons,
|
|
"mock_pose_data": settings.mock_pose_data,
|
|
"models": [model.dict() for model in domain_config.pose_models],
|
|
}
|
|
|
|
return config
|
|
|
|
def get_streaming_config(self) -> Dict[str, Any]:
|
|
"""Get streaming configuration."""
|
|
settings = self.settings
|
|
domain_config = self.domain_config
|
|
|
|
config = {
|
|
"fps": settings.stream_fps,
|
|
"buffer_size": settings.stream_buffer_size,
|
|
"websocket_ping_interval": settings.websocket_ping_interval,
|
|
"websocket_timeout": settings.websocket_timeout,
|
|
"enable_websockets": settings.enable_websockets,
|
|
"enable_real_time_processing": settings.enable_real_time_processing,
|
|
"max_connections": domain_config.streaming.max_connections,
|
|
"compression": domain_config.streaming.compression,
|
|
}
|
|
|
|
return config
|
|
|
|
def get_storage_config(self) -> Dict[str, Any]:
|
|
"""Get storage configuration."""
|
|
settings = self.settings
|
|
|
|
config = {
|
|
"data_path": Path(settings.data_storage_path),
|
|
"model_path": Path(settings.model_storage_path),
|
|
"temp_path": Path(settings.temp_storage_path),
|
|
"max_size_gb": settings.max_storage_size_gb,
|
|
"enable_historical_data": settings.enable_historical_data,
|
|
}
|
|
|
|
# Ensure directories exist
|
|
for path in [config["data_path"], config["model_path"], config["temp_path"]]:
|
|
path.mkdir(parents=True, exist_ok=True)
|
|
|
|
return config
|
|
|
|
def get_monitoring_config(self) -> Dict[str, Any]:
|
|
"""Get monitoring configuration."""
|
|
settings = self.settings
|
|
|
|
config = {
|
|
"metrics_enabled": settings.metrics_enabled,
|
|
"health_check_interval": settings.health_check_interval,
|
|
"performance_monitoring": settings.performance_monitoring,
|
|
"log_level": settings.log_level,
|
|
"log_file": settings.log_file,
|
|
}
|
|
|
|
return config
|
|
|
|
def get_rate_limiting_config(self) -> Dict[str, Any]:
|
|
"""Get rate limiting configuration."""
|
|
settings = self.settings
|
|
|
|
config = {
|
|
"enabled": settings.enable_rate_limiting,
|
|
"requests": settings.rate_limit_requests,
|
|
"authenticated_requests": settings.rate_limit_authenticated_requests,
|
|
"window": settings.rate_limit_window,
|
|
}
|
|
|
|
return config
|
|
|
|
def validate_configuration(self) -> List[str]:
|
|
"""Validate complete configuration and return issues."""
|
|
issues = []
|
|
|
|
try:
|
|
# Validate settings
|
|
from src.config.settings import validate_settings
|
|
settings_issues = validate_settings(self.settings)
|
|
issues.extend(settings_issues)
|
|
|
|
# Validate database configuration
|
|
try:
|
|
db_config = self.get_database_config()
|
|
if not db_config["url"]:
|
|
issues.append("Database URL is not configured")
|
|
except Exception as e:
|
|
issues.append(f"Database configuration error: {e}")
|
|
|
|
# Validate storage paths
|
|
try:
|
|
storage_config = self.get_storage_config()
|
|
for name, path in storage_config.items():
|
|
if name.endswith("_path") and not path.exists():
|
|
issues.append(f"Storage path does not exist: {path}")
|
|
except Exception as e:
|
|
issues.append(f"Storage configuration error: {e}")
|
|
|
|
# Validate hardware configuration
|
|
try:
|
|
hw_config = self.get_hardware_config()
|
|
if not hw_config["routers"]:
|
|
issues.append("No routers configured")
|
|
except Exception as e:
|
|
issues.append(f"Hardware configuration error: {e}")
|
|
|
|
# Validate pose configuration
|
|
try:
|
|
pose_config = self.get_pose_config()
|
|
if not pose_config["models"]:
|
|
issues.append("No pose models configured")
|
|
except Exception as e:
|
|
issues.append(f"Pose configuration error: {e}")
|
|
|
|
except Exception as e:
|
|
issues.append(f"Configuration validation error: {e}")
|
|
|
|
return issues
|
|
|
|
def get_full_config(self) -> Dict[str, Any]:
|
|
"""Get complete configuration dictionary."""
|
|
return {
|
|
"settings": self.settings.dict(),
|
|
"domain_config": self.domain_config.to_dict(),
|
|
"database": self.get_database_config(),
|
|
"redis": self.get_redis_config(),
|
|
"security": self.get_security_config(),
|
|
"hardware": self.get_hardware_config(),
|
|
"pose": self.get_pose_config(),
|
|
"streaming": self.get_streaming_config(),
|
|
"storage": self.get_storage_config(),
|
|
"monitoring": self.get_monitoring_config(),
|
|
"rate_limiting": self.get_rate_limiting_config(),
|
|
}
|
|
|
|
|
|
# Global configuration manager instance
|
|
@lru_cache()
|
|
def get_config_manager() -> ConfigManager:
|
|
"""Get cached configuration manager instance."""
|
|
return ConfigManager()
|
|
|
|
|
|
# Convenience functions
|
|
def get_app_settings() -> Settings:
|
|
"""Get application settings."""
|
|
return get_config_manager().settings
|
|
|
|
|
|
def get_app_domain_config() -> DomainConfig:
|
|
"""Get domain configuration."""
|
|
return get_config_manager().domain_config
|
|
|
|
|
|
def validate_app_configuration() -> List[str]:
|
|
"""Validate application configuration."""
|
|
return get_config_manager().validate_configuration()
|
|
|
|
|
|
def reload_configuration():
|
|
"""Reload all configuration."""
|
|
config_manager = get_config_manager()
|
|
config_manager.reload_settings()
|
|
config_manager.reload_domain_config()
|
|
logger.info("Configuration reloaded") |