"""Application configuration loaded from environment variables or a local .env file.""" from pydantic import Field from pydantic_settings import BaseSettings from typing import Literal LEGACY_DEFAULT_SECRET = "change-me-to-a-long-random-string" class Settings(BaseSettings): # ---------- 运行环境 ---------- environment: Literal["development", "test", "production"] = "development" auth_enabled: bool = False # ---------- 数据库 ---------- DATABASE_URL: str = "sqlite+aiosqlite:///./pingwatch.db" # PostgreSQL: "postgresql+asyncpg://user:pass@localhost/pingwatch" # ---------- 企业微信 ---------- WECOM_CORP_ID: str = "" WECOM_AGENT_ID: int = 0 WECOM_APP_SECRET: str = "" # ---------- Casdoor ---------- casdoor_endpoint: str = "https://casdoor.dhdx.fun" CASDOOR_CLIENT_ID: str = "" CASDOOR_CLIENT_SECRET: str = "" CASDOOR_CERTIFICATE: str = "" # 可选,用于验证 id_token 签名 CASDOOR_ORGANIZATION: str = "dahua" CASDOOR_APPLICATION: str = "PingWatch" CASDOOR_REDIRECT_URI: str = "http://10.10.10.7:5173/login" # 前端回调地址 # ---------- 连通性监测 ---------- probe_packets_per_round: int = Field(default=3, ge=1, le=10) offline_consecutive_rounds: int = Field(default=2, ge=1, le=10) degraded_window_rounds: int = Field(default=5, ge=2, le=60) degraded_loss_percent: float = Field(default=20.0, ge=1, le=100) recovery_consecutive_clean_rounds: int = Field(default=3, ge=1, le=20) # ---------- 企业微信投递 ---------- wecom_notification_enabled: bool = False wecom_notification_max_attempts: int = Field(default=5, ge=1, le=10) wecom_retry_base_seconds: int = Field(default=30, ge=1, le=3600) WECOM_TO_PARTY: str = "" # ---------- Ping 引擎 ---------- PING_INTERVAL_SECONDS: int = 30 PING_TIMEOUT_SECONDS: float = 5.0 DEFAULT_ALERT_THRESHOLD: int = 5 PING_CONCURRENCY: int = 50 FPING_PATH: str = "/usr/bin/fping" # ---------- 上游心跳 ---------- UPSTREAM_PING_TARGET: str = "114.114.114.114" UPSTREAM_PING_THRESHOLD: int = 2 OFFLINE_SUPPRESS_RATIO: float = 0.9 # ---------- 数据保留 ---------- PING_RECORD_RETENTION_DAYS: int = 90 ALERT_RETENTION_DAYS: int = 365 # ---------- JWT ---------- secret_key: str = LEGACY_DEFAULT_SECRET ACCESS_TOKEN_EXPIRE_MINUTES: int = 480 # ---------- LogHive ---------- LOGHIVE_ENDPOINT: str = "http://10.10.10.14:8000" LOGHIVE_PROJECT: str = "PingWatch" LOGHIVE_API_KEY: str = "" # ---------- CORS ---------- CORS_ORIGINS: str = "http://localhost:5173,http://10.10.10.7:5173,http://10.10.10.7" model_config = {"env_file": ".env", "env_file_encoding": "utf-8", "extra": "ignore"} @property def CASDOOR_ENDPOINT(self) -> str: """Compatibility accessor for existing uppercase configuration consumers.""" return self.casdoor_endpoint @property def SECRET_KEY(self) -> str: """Compatibility accessor for existing uppercase configuration consumers.""" return self.secret_key settings = Settings()