from typing import Optional from pydantic import AliasChoices, Field from pydantic_settings import BaseSettings, SettingsConfigDict from .build_info import BUILD_NUMBER, CHANGELOG class Settings(BaseSettings): model_config = SettingsConfigDict(env_prefix="") app_name: str = "Magent" cors_allow_origin: str = "http://localhost:3000" sqlite_path: str = Field(default="data/magent.db", validation_alias=AliasChoices("SQLITE_PATH")) sqlite_journal_mode: str = Field( default="DELETE", validation_alias=AliasChoices("SQLITE_JOURNAL_MODE") ) jwt_secret: str = Field(default="change-me", validation_alias=AliasChoices("JWT_SECRET")) jwt_exp_minutes: int = Field(default=720, validation_alias=AliasChoices("JWT_EXP_MINUTES")) api_docs_enabled: bool = Field(default=False, validation_alias=AliasChoices("API_DOCS_ENABLED")) auth_rate_limit_window_seconds: int = Field( default=60, validation_alias=AliasChoices("AUTH_RATE_LIMIT_WINDOW_SECONDS") ) auth_rate_limit_max_attempts_ip: int = Field( default=15, validation_alias=AliasChoices("AUTH_RATE_LIMIT_MAX_ATTEMPTS_IP") ) auth_rate_limit_max_attempts_user: int = Field( default=5, validation_alias=AliasChoices("AUTH_RATE_LIMIT_MAX_ATTEMPTS_USER") ) password_reset_rate_limit_window_seconds: int = Field( default=300, validation_alias=AliasChoices("PASSWORD_RESET_RATE_LIMIT_WINDOW_SECONDS") ) password_reset_rate_limit_max_attempts_ip: int = Field( default=6, validation_alias=AliasChoices("PASSWORD_RESET_RATE_LIMIT_MAX_ATTEMPTS_IP") ) password_reset_rate_limit_max_attempts_identifier: int = Field( default=3, validation_alias=AliasChoices("PASSWORD_RESET_RATE_LIMIT_MAX_ATTEMPTS_IDENTIFIER") ) admin_username: str = Field(default="admin", validation_alias=AliasChoices("ADMIN_USERNAME")) admin_password: str = Field(default="adminadmin", validation_alias=AliasChoices("ADMIN_PASSWORD")) log_level: str = Field(default="INFO", validation_alias=AliasChoices("LOG_LEVEL")) log_file: str = Field(default="data/magent.log", validation_alias=AliasChoices("LOG_FILE")) log_file_max_bytes: int = Field( default=20_000_000, validation_alias=AliasChoices("LOG_FILE_MAX_BYTES") ) log_file_backup_count: int = Field( default=10, validation_alias=AliasChoices("LOG_FILE_BACKUP_COUNT") ) log_http_client_level: str = Field( default="INFO", validation_alias=AliasChoices("LOG_HTTP_CLIENT_LEVEL") ) log_background_sync_level: str = Field( default="INFO", validation_alias=AliasChoices("LOG_BACKGROUND_SYNC_LEVEL") ) requests_sync_ttl_minutes: int = Field( default=1440, validation_alias=AliasChoices("REQUESTS_SYNC_TTL_MINUTES") ) requests_poll_interval_seconds: int = Field( default=300, validation_alias=AliasChoices("REQUESTS_POLL_INTERVAL_SECONDS") ) requests_delta_sync_interval_minutes: int = Field( default=5, validation_alias=AliasChoices("REQUESTS_DELTA_SYNC_INTERVAL_MINUTES") ) requests_full_sync_time: str = Field( default="00:00", validation_alias=AliasChoices("REQUESTS_FULL_SYNC_TIME") ) requests_cleanup_time: str = Field( default="02:00", validation_alias=AliasChoices("REQUESTS_CLEANUP_TIME") ) requests_cleanup_days: int = Field( default=90, validation_alias=AliasChoices("REQUESTS_CLEANUP_DAYS") ) requests_data_source: str = Field( default="prefer_cache", validation_alias=AliasChoices("REQUESTS_DATA_SOURCE") ) artwork_cache_mode: str = Field( default="remote", validation_alias=AliasChoices("ARTWORK_CACHE_MODE") ) site_build_number: Optional[str] = Field(default=BUILD_NUMBER) site_banner_enabled: bool = Field( default=False, validation_alias=AliasChoices("SITE_BANNER_ENABLED") ) site_banner_message: Optional[str] = Field( default=None, validation_alias=AliasChoices("SITE_BANNER_MESSAGE") ) site_banner_tone: str = Field( default="info", validation_alias=AliasChoices("SITE_BANNER_TONE") ) site_login_show_jellyfin_login: bool = Field( default=True, validation_alias=AliasChoices("SITE_LOGIN_SHOW_JELLYFIN_LOGIN") ) site_login_show_local_login: bool = Field( default=True, validation_alias=AliasChoices("SITE_LOGIN_SHOW_LOCAL_LOGIN") ) site_login_show_forgot_password: bool = Field( default=True, validation_alias=AliasChoices("SITE_LOGIN_SHOW_FORGOT_PASSWORD") ) site_login_show_signup_link: bool = Field( default=True, validation_alias=AliasChoices("SITE_LOGIN_SHOW_SIGNUP_LINK") ) site_changelog: Optional[str] = Field(default=CHANGELOG) magent_application_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_APPLICATION_URL") ) magent_application_port: int = Field( default=3000, validation_alias=AliasChoices("MAGENT_APPLICATION_PORT") ) magent_api_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_API_URL") ) magent_api_port: int = Field( default=8000, validation_alias=AliasChoices("MAGENT_API_PORT") ) magent_bind_host: str = Field( default="0.0.0.0", validation_alias=AliasChoices("MAGENT_BIND_HOST") ) magent_proxy_enabled: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_PROXY_ENABLED") ) magent_proxy_base_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_PROXY_BASE_URL") ) magent_proxy_trust_forwarded_headers: bool = Field( default=True, validation_alias=AliasChoices("MAGENT_PROXY_TRUST_FORWARDED_HEADERS") ) magent_proxy_forwarded_prefix: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_PROXY_FORWARDED_PREFIX") ) magent_ssl_bind_enabled: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_SSL_BIND_ENABLED") ) magent_ssl_certificate_path: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_SSL_CERTIFICATE_PATH") ) magent_ssl_private_key_path: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_SSL_PRIVATE_KEY_PATH") ) magent_ssl_certificate_pem: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_SSL_CERTIFICATE_PEM") ) magent_ssl_private_key_pem: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_SSL_PRIVATE_KEY_PEM") ) magent_notify_enabled: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_NOTIFY_ENABLED") ) magent_notify_email_enabled: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_ENABLED") ) magent_notify_email_smtp_host: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_SMTP_HOST") ) magent_notify_email_smtp_port: int = Field( default=587, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_SMTP_PORT") ) magent_notify_email_smtp_username: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_SMTP_USERNAME") ) magent_notify_email_smtp_password: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_SMTP_PASSWORD") ) magent_notify_email_from_address: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_FROM_ADDRESS") ) magent_notify_email_from_name: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_FROM_NAME") ) magent_notify_email_use_tls: bool = Field( default=True, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_USE_TLS") ) magent_notify_email_use_ssl: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_NOTIFY_EMAIL_USE_SSL") ) magent_notify_discord_enabled: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_NOTIFY_DISCORD_ENABLED") ) magent_notify_discord_webhook_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_DISCORD_WEBHOOK_URL") ) magent_notify_telegram_enabled: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_NOTIFY_TELEGRAM_ENABLED") ) magent_notify_telegram_bot_token: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_TELEGRAM_BOT_TOKEN") ) magent_notify_telegram_chat_id: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_TELEGRAM_CHAT_ID") ) magent_notify_push_enabled: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_NOTIFY_PUSH_ENABLED") ) magent_notify_push_provider: Optional[str] = Field( default="ntfy", validation_alias=AliasChoices("MAGENT_NOTIFY_PUSH_PROVIDER") ) magent_notify_push_base_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_PUSH_BASE_URL") ) magent_notify_push_topic: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_PUSH_TOPIC") ) magent_notify_push_token: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_PUSH_TOKEN") ) magent_notify_push_user_key: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_PUSH_USER_KEY") ) magent_notify_push_device: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_PUSH_DEVICE") ) magent_notify_webhook_enabled: bool = Field( default=False, validation_alias=AliasChoices("MAGENT_NOTIFY_WEBHOOK_ENABLED") ) magent_notify_webhook_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("MAGENT_NOTIFY_WEBHOOK_URL") ) jellyseerr_base_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("JELLYSEERR_URL", "JELLYSEERR_BASE_URL") ) jellyseerr_api_key: Optional[str] = Field( default=None, validation_alias=AliasChoices("JELLYSEERR_API_KEY", "JELLYSEERR_KEY") ) jellyfin_base_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("JELLYFIN_URL", "JELLYFIN_BASE_URL") ) jellyfin_api_key: Optional[str] = Field( default=None, validation_alias=AliasChoices("JELLYFIN_API_KEY", "JELLYFIN_KEY") ) jellyfin_public_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("JELLYFIN_PUBLIC_URL") ) jellyfin_sync_to_arr: bool = Field( default=True, validation_alias=AliasChoices("JELLYFIN_SYNC_TO_ARR") ) sonarr_base_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("SONARR_URL", "SONARR_BASE_URL") ) sonarr_api_key: Optional[str] = Field( default=None, validation_alias=AliasChoices("SONARR_API_KEY", "SONARR_KEY") ) sonarr_quality_profile_id: Optional[int] = Field( default=None, validation_alias=AliasChoices("SONARR_QUALITY_PROFILE_ID") ) sonarr_root_folder: Optional[str] = Field( default=None, validation_alias=AliasChoices("SONARR_ROOT_FOLDER") ) sonarr_qbittorrent_category: Optional[str] = Field( default="sonarr", validation_alias=AliasChoices("SONARR_QBITTORRENT_CATEGORY"), ) radarr_base_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("RADARR_URL", "RADARR_BASE_URL") ) radarr_api_key: Optional[str] = Field( default=None, validation_alias=AliasChoices("RADARR_API_KEY", "RADARR_KEY") ) radarr_quality_profile_id: Optional[int] = Field( default=None, validation_alias=AliasChoices("RADARR_QUALITY_PROFILE_ID") ) radarr_root_folder: Optional[str] = Field( default=None, validation_alias=AliasChoices("RADARR_ROOT_FOLDER") ) radarr_qbittorrent_category: Optional[str] = Field( default="radarr", validation_alias=AliasChoices("RADARR_QBITTORRENT_CATEGORY"), ) prowlarr_base_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("PROWLARR_URL", "PROWLARR_BASE_URL") ) prowlarr_api_key: Optional[str] = Field( default=None, validation_alias=AliasChoices("PROWLARR_API_KEY", "PROWLARR_KEY") ) qbittorrent_base_url: Optional[str] = Field( default=None, validation_alias=AliasChoices("QBIT_URL", "QBITTORRENT_URL", "QBITTORRENT_BASE_URL") ) qbittorrent_username: Optional[str] = Field( default=None, validation_alias=AliasChoices("QBIT_USERNAME", "QBITTORRENT_USERNAME") ) qbittorrent_password: Optional[str] = Field( default=None, validation_alias=AliasChoices("QBIT_PASSWORD", "QBITTORRENT_PASSWORD") ) discord_webhook_url: Optional[str] = Field( default="https://discord.com/api/webhooks/1464141924775629033/O_rvCAmIKowR04tyAN54IuMPcQFEiT-ustU3udDaMTlF62PmoI6w4-52H3ZQcjgHQOgt", validation_alias=AliasChoices("DISCORD_WEBHOOK_URL"), ) settings = Settings()