Перейти к содержанию

Архитектура

Pyromax отделяет пользовательский API от деталей обмена с MAX. Благодаря этому роутинг не зависит от конкретного протокола, а backend можно заменять через реестры.

Обработчики приложения
        ↑ типизированные данные / методы моделей
Dispatcher → Router → Observer → Filters → Middleware → Handler
        ↑
Доменные модели (Message, Chat, Contact, ...)
        ↑↓
Mapper (EnvelopeV11)
        ↑↓
Protocol (EnvelopeProtocol)
        ↑↓
Transport (websocket или socket envelope)
        ↑↓
MAX Messenger

Клиентский стек

MaxApi выбирает классы из реестров транспорта, протокола и маппера. Создание асинхронное, потому что соединение и авторизация выполняют I/O. Маппер предоставляет высокоуровневые операции и переводит protocol payload в доменные Pydantic-модели.

Путь события

  1. MaxApi.listen_updates() возвращает переводчик ответов и асинхронный поток.
  2. Dispatcher.start_polling() превращает каждый ответ в доменное событие.
  3. Внешние middleware обогащают контекст, обрабатывают ошибки и при необходимости создают FSMContext.
  4. Observer выбирает обработчики нужного типа события.
  5. Фильтры выполняются по порядку. False отклоняет обработчик, словарь добавляет значения в DI-контекст.
  6. Middleware оборачивают выбранный обработчик.
  7. Аргументы обработчика разрешаются по аннотациям типов или строковым forward reference.

Публичные и внутренние слои

  • В приложении предпочитайте MaxApi и методы привязанных моделей.
  • Для структуры используйте Router, observers, filters, middleware и FSM.
  • Реестры транспорта, протокола и маппера расширяйте только при реализации backend.
  • mapping.envelope.v11.payloads, immutable builders и DTO translators — внутренние protocol-слои, которые могут меняться быстрее высокоуровневого API.

Жизненный цикл

Dispatcher владеет polling-циклом и закрывает FSM middleware при остановке. Модели, созданные маппером, привязаны к исходному MaxApi; поэтому работают методы message.reply() и chat.history().