"""Модуль конфигурации приложения.
Предоставляет настройки приложения через переменные окружения.
"""
import os
from dataclasses import dataclass
from typing import ClassVar
@dataclass(frozen=True, slots=True)
class Settings:
"""Настройки приложения.
:param bitrix_webhook_url: URL вебхука Bitrix24.
:param log_level: Уровень логирования (DEBUG, INFO, WARNING, ERROR, CRITICAL).
:param mcp_transport: Транспорт MCP (stdio, streamable-http, sse).
:param mcp_host: Хост для HTTP транспорта.
:param mcp_port: Порт для HTTP транспорта.
"""
BITRIX_WEBHOOK_URL: str
LOG_LEVEL: str = "INFO"
MCP_TRANSPORT: str = "sse"
MCP_HOST: str = "0.0.0.0"
MCP_PORT: int = 8000
# Yandex Cloud (для бота)
YANDEX_FOLDER_ID: str = ""
YANDEX_API_KEY: str = ""
class SettingsManager:
"""Менеджер настроек приложения.
Реализует паттерн Singleton для управления настройками.
"""
_instance: ClassVar[Settings | None] = None
@classmethod
def init(cls) -> Settings:
"""Инициализация настроек приложения.
:return: Экземпляр настроек.
:raises ValueError: Если не указан URL вебхука.
"""
if cls._instance is None:
webhook_url = os.getenv("BITRIX_WEBHOOK_URL")
log_level = os.getenv("LOG_LEVEL", "INFO")
mcp_transport = os.getenv("MCP_TRANSPORT", "sse")
mcp_host = os.getenv("MCP_HOST", "0.0.0.0")
mcp_port = int(os.getenv("MCP_PORT", "8000"))
yandex_folder_id = os.getenv("YANDEX_FOLDER_ID", "")
yandex_api_key = os.getenv("YANDEX_API_KEY", "")
if not webhook_url:
msg = (
"Не указана переменная окружения BITRIX_WEBHOOK_URL. "
"Пожалуйста, укажите URL вебхука Bitrix24.",
)
raise ValueError(msg)
cls._instance = Settings(
BITRIX_WEBHOOK_URL=webhook_url,
LOG_LEVEL=log_level,
MCP_TRANSPORT=mcp_transport,
MCP_HOST=mcp_host,
MCP_PORT=mcp_port,
YANDEX_FOLDER_ID=yandex_folder_id,
YANDEX_API_KEY=yandex_api_key,
)
return cls._instance
@classmethod
def get(cls) -> Settings:
"""Получение текущих настроек приложения.
:return: Экземпляр настроек.
"""
if cls._instance is None:
return cls.init()
return cls._instance