67 lines
1.8 KiB
Python
67 lines
1.8 KiB
Python
# app.config
|
|
|
|
from pydantic import BaseModel, HttpUrl, field_validator
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class SiteConfig(BaseModel):
|
|
"""Schema for a single monitored site."""
|
|
name: str
|
|
url: HttpUrl
|
|
timeout_seconds: int = 10
|
|
expected_status: int = 200
|
|
expected_keywords: list[str] = []
|
|
max_retries: int = 1
|
|
|
|
@field_validator("timeout_seconds")
|
|
@classmethod
|
|
def timeout_must_be_positive(cls, v: int) -> int:
|
|
if v <= 0:
|
|
raise ValueError("timeout_seconds must be a positive integer")
|
|
return v
|
|
|
|
def to_dict(self) -> dict:
|
|
"""Return a plain dict compatible with check_site() in utils.py."""
|
|
return {
|
|
"name": self.name,
|
|
"url": str(self.url),
|
|
"timeout_seconds": self.timeout_seconds,
|
|
"expected_status": self.expected_status,
|
|
"expected_keywords": self.expected_keywords,
|
|
"max_retries": self.max_retries,
|
|
}
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(
|
|
env_file=".env",
|
|
env_file_encoding="utf-8",
|
|
)
|
|
|
|
# Discord
|
|
discord_secret_key: str
|
|
discord_client_id: str = ""
|
|
discord_client_secret: str = ""
|
|
|
|
# Database
|
|
database_path: str = "uptime.db"
|
|
|
|
# Polling — how often to check all sites (minimum 1 minute)
|
|
poll_interval_minutes: int = 15
|
|
|
|
# Alerts — set alert_channel_id to 0 to disable
|
|
alert_channel_id: int = 0
|
|
alert_cooldown_minutes: int = 30
|
|
|
|
# Sites — stored as a JSON array string in .env:
|
|
monitored_sites: list[SiteConfig] = []
|
|
|
|
@field_validator("poll_interval_minutes")
|
|
@classmethod
|
|
def poll_interval_must_be_positive(cls, v: int) -> int:
|
|
if v < 1:
|
|
raise ValueError("poll_interval_minutes must be at least 1")
|
|
return v
|
|
|
|
|
|
settings = Settings() |