Реализована интеграция с СМС провайдером

This commit is contained in:
mi
2026-07-23 11:49:15 +03:00
parent cc0163eb94
commit b1ed714d5b
89 changed files with 5934 additions and 202 deletions
@@ -0,0 +1,53 @@
from functools import lru_cache
from pydantic import AnyHttpUrl, Field, SecretStr, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=None, extra="ignore")
database_url: str = Field(alias="SMS_DATABASE_URL")
service_token: SecretStr = Field(alias="SMS_SERVICE_TOKEN", min_length=32)
idgtl_base_url: AnyHttpUrl = Field(
default=AnyHttpUrl("https://direct.i-dgtl.ru"), alias="IDGTL_SMS_BASE_URL"
)
idgtl_api_key: SecretStr | None = Field(default=None, alias="IDGTL_SMS_API_KEY")
callback_public_url: AnyHttpUrl = Field(alias="IDGTL_SMS_CALLBACK_PUBLIC_URL")
callback_username: SecretStr = Field(alias="IDGTL_SMS_CALLBACK_USERNAME")
callback_password: SecretStr = Field(alias="IDGTL_SMS_CALLBACK_PASSWORD")
log_level: str = Field(default="INFO", alias="LOG_LEVEL")
api_port: int = Field(default=8080, alias="SMS_API_PORT", ge=1, le=65535)
@field_validator(
"service_token",
"callback_username",
"callback_password",
)
@classmethod
def reject_placeholders(cls, value: SecretStr) -> SecretStr:
raw = value.get_secret_value().strip()
if not raw or raw.lower() in {"changeme", "secret", "token", "<secret>"}:
raise ValueError("secret is missing or is a placeholder")
return value
@field_validator("idgtl_api_key")
@classmethod
def reject_api_key_placeholder(cls, value: SecretStr | None) -> SecretStr | None:
if value is None:
return None
return cls.reject_placeholders(value)
@field_validator("callback_public_url")
@classmethod
def callback_must_be_https(cls, value: AnyHttpUrl) -> AnyHttpUrl:
if value.scheme != "https":
raise ValueError("callback URL must use HTTPS")
if value.username or value.password:
raise ValueError("callback URL must not contain credentials")
return value
@lru_cache
def get_settings() -> Settings:
return Settings()