Files
healthbot/src/utils/env.py
T

84 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from pydantic import Field, SecretStr, computed_field
from pydantic_settings import BaseSettings, SettingsConfigDict
class BotSettings(BaseSettings):
token: SecretStr
class MonitorSettings(BaseSettings):
check_interval: int = 30 # как часто пинговать сервисы, сек
reminder_interval: int = 1800 # как часто напоминать что всё ещё лежит, сек
request_timeout: int = 10 # таймаут одного запроса, сек
# Сколько проверок подряд должны провалиться, прежде чем объявить падение.
# Одна неудачная проверка — это обычно моргнувшая сеть, а не упавший
# сервис. При 1 бот будит по любому чиху; при 2 ложные тревоги почти
# исчезают, а реакция замедляется всего на один интервал.
failure_threshold: int = 2
# Сколько символов ответа показывать в уведомлении.
body_preview: int = 400
class KomodoSettings(BaseSettings):
"""Связь с Komodo. Всё опционально — без неё бот работает как раньше."""
url: str = "" # https://komod.example.com
key: SecretStr = SecretStr("")
secret: SecretStr = SecretStr("")
timeout: int = 20
@computed_field
@property
def enabled(self) -> bool:
return bool(self.url and self.key.get_secret_value())
class WebSettings(BaseSettings):
"""Приёмник входящих алертов (Komodo Alerter с endpoint type Custom)."""
enabled: bool = False
host: str = "0.0.0.0" # noqa: S104
port: int = 8080
# Общий секрет. Komodo произвольные заголовки слать не умеет, поэтому
# принимаем и в X-Alert-Token, и в query-параметре ?token=
token: SecretStr = SecretStr("")
class DbSettings(BaseSettings):
path: str = "data/healthbot.db"
class LogSettings(BaseSettings):
level: str = "INFO"
level_external: str = "WARNING"
show_time: bool = False
console_width: int = 150
class Settings(BaseSettings):
# Оставлено для совместимости: раньше админ был ровно один.
admin_id: int = 0
# Несколько админов — чтобы бот годился не только владельцу-одиночке.
admin_ids: list[int] = Field(default_factory=list)
bot: BotSettings = Field(default_factory=BotSettings)
monitor: MonitorSettings = Field(default_factory=MonitorSettings)
komodo: KomodoSettings = Field(default_factory=KomodoSettings)
web: WebSettings = Field(default_factory=WebSettings)
db: DbSettings = Field(default_factory=DbSettings)
log: LogSettings = Field(default_factory=LogSettings)
model_config = SettingsConfigDict(
case_sensitive=False, env_file=".env", env_nested_delimiter="__", extra="ignore"
)
@computed_field
@property
def admins(self) -> set[int]:
return {i for i in (self.admin_id, *self.admin_ids) if i}
env = Settings()