95 lines
2.7 KiB
Python
95 lines
2.7 KiB
Python
"""
|
|
©AngelaMos | 2026
|
|
config.py
|
|
|
|
Pydantic-settings application configuration loaded from
|
|
environment variables and .env file
|
|
|
|
Defines the Settings model with defaults for: server
|
|
(host 0.0.0.0, port 8000, debug, log_level), database
|
|
(postgresql+asyncpg URL), Redis URL, GeoIP MaxMind
|
|
database path, nginx log path, pipeline queue sizes
|
|
(raw 1000, parsed 500, feature 200, alert 100), batch
|
|
settings (size 32, timeout 50ms), and ML configuration
|
|
(model_dir, detection_mode, ensemble weights for
|
|
autoencoder/random-forest/isolation-forest at 0.40/0.40
|
|
/0.20 with model_validator enforcing sum-to-1.0,
|
|
ae_threshold_percentile 99.5, MLflow tracking URI).
|
|
Exports a module-level singleton settings instance
|
|
|
|
Connects to:
|
|
factory.py - consumed in lifespan and create_app
|
|
__main__.py - server host/port/reload
|
|
core/ingestion/ - queue sizes, log path
|
|
core/detection/ - model_dir, ensemble weights
|
|
core/enrichment/ - geoip_db_path
|
|
"""
|
|
|
|
from typing import Self
|
|
|
|
from pydantic import model_validator
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
"""
|
|
Application configuration loaded from environment variables.
|
|
"""
|
|
|
|
model_config = SettingsConfigDict(
|
|
env_file=".env",
|
|
env_file_encoding="utf-8",
|
|
case_sensitive=False,
|
|
)
|
|
|
|
app_name: str = "AngelusVigil"
|
|
env: str = "development"
|
|
debug: bool = False
|
|
host: str = "0.0.0.0"
|
|
port: int = 8000
|
|
api_key: str = ""
|
|
log_level: str = "INFO"
|
|
|
|
database_url: str = "postgresql+asyncpg://vigil:changeme@localhost:5432/angelusvigil"
|
|
|
|
redis_url: str = "redis://localhost:6379"
|
|
|
|
geoip_db_path: str = "/usr/share/GeoIP/GeoLite2-City.mmdb"
|
|
|
|
nginx_log_path: str = "/var/log/nginx/access.log"
|
|
|
|
raw_queue_size: int = 1000
|
|
parsed_queue_size: int = 500
|
|
feature_queue_size: int = 200
|
|
alert_queue_size: int = 100
|
|
|
|
batch_size: int = 32
|
|
batch_timeout_ms: int = 50
|
|
|
|
model_dir: str = "data/models"
|
|
detection_mode: str = "rules"
|
|
ensemble_weight_ae: float = 0.40
|
|
ensemble_weight_rf: float = 0.40
|
|
ensemble_weight_if: float = 0.20
|
|
ae_threshold_percentile: float = 99.5
|
|
mlflow_tracking_uri: str = "file:./mlruns"
|
|
|
|
@model_validator(mode="after")
|
|
def _check_ensemble_weights(self) -> Self:
|
|
"""
|
|
Validate that ensemble weights sum to 1.0
|
|
"""
|
|
total = (
|
|
self.ensemble_weight_ae
|
|
+ self.ensemble_weight_rf
|
|
+ self.ensemble_weight_if
|
|
)
|
|
if abs(total - 1.0) > 1e-6:
|
|
raise ValueError(
|
|
f"Ensemble weights must sum to 1.0, got {total:.6f}"
|
|
)
|
|
return self
|
|
|
|
|
|
settings = Settings()
|