Архитектура¶
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-модели.
Путь события¶
MaxApi.listen_updates()возвращает переводчик ответов и асинхронный поток.Dispatcher.start_polling()превращает каждый ответ в доменное событие.- Внешние middleware обогащают контекст, обрабатывают ошибки и при необходимости создают
FSMContext. - Observer выбирает обработчики нужного типа события.
- Фильтры выполняются по порядку.
Falseотклоняет обработчик, словарь добавляет значения в DI-контекст. - Middleware оборачивают выбранный обработчик.
- Аргументы обработчика разрешаются по аннотациям типов или строковым 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().