Фасады#

Фасады - это обёртки, упрощающие взаимодействие с API и управление контекстом события. Они автоматически внедряются в аргументы обработчиков, если указать соответствующий тип.

Зачем нужны фасады?#

Обычно, чтобы отправить сообщение в ответ пользователю, нужно знать chat_id или user_id и вручную вызывать методы бота. В классическом подходе это выглядит так:

await bot.send_message(chat_id=chat_id, text="Hello!")

С использованием фасада код становится короче и понятнее, так как фасад уже знает контекст текущего обновления (в каком чате произошло событие, кто его инициатор):

# В аргументах хендлера: facade: MessageCreatedFacade
await facade.answer_text("Hello!")

Основные возможности#

  • Быстрые ответы: методы answer_text, reply_text, send_media и другие автоматически подставляют нужные ID.

  • Управление клавиатурами: методы для быстрой отправки или редактирования клавиатур.

  • Доступ к боту: через свойство facade.bot всегда доступен экземпляр бота.

Отправка медиа#

Фасады поддерживают отправку медиа двумя способами:

  • Загрузка файла - через InputFile (BufferedInputFile, FSInputFile). Файл загружается на сервер автоматически.

  • По токену - через MediaAttachmentsRequests (PhotoAttachmentRequest, VideoAttachmentRequest и т.д.). Используется, когда медиа уже загружено ранее и известен его токен.

Оба варианта можно передавать в параметр media методов send_message, send_media и edit_message. Тип MediaInput объединяет оба варианта:

from maxo.routing.mixins.attachments import MediaInput

Загрузка файла#

from maxo.utils.upload_media import BufferedInputFile

photo = BufferedInputFile.image(content, "photo.jpg")
await facade.send_media(media=photo, text="Новое фото")

Все настройки загрузки собраны в maxo.bot.UploadConfig и передаются в Bot(upload_config=...). Способ выбирается полем method (maxo.bot.UploadMethod):

  • AUTO (по умолчанию) - большие файлы грузятся resumable-протоколом (частями), мелкие - одним запросом. Порог - resumable_threshold.

  • RESUMABLE - всегда частями.

  • SINGLE - всегда одним multipart-запросом.

В UploadConfig также задаются размер куска и ретраи resumable-загрузки, ретраи отправки при attachment.not.ready и модель ожидания обработки файла сервером. Для больших файлов повышайте not_ready_max_retries - сервер обрабатывает многогигабайтные файлы дольше.

Resumable-загрузка читает файл по кускам и отправляет их последовательными запросами. Для FSInputFile это значит, что большой файл стримится прямо с диска и не держится в памяти целиком - так снимается лимит на размер (обычный однозапросный аплоад падает на файлах около 2 ГБ). Для больших файлов предпочитайте FSInputFile:

from maxo import Bot
from maxo.bot import UploadConfig, UploadMethod
from maxo.utils.upload_media import FSInputFile

# AUTO - значение по умолчанию; для очень больших файлов даём больше ретраев
config = UploadConfig(method=UploadMethod.AUTO, not_ready_max_retries=30)
bot = Bot(token, upload_config=config)

video = FSInputFile.video("/path/to/large_video.mp4")
await facade.send_media(media=video, text="Большое видео")

Отправка по токену#

Если медиа уже было загружено или получено из входящего сообщения, можно использовать токен напрямую:

from maxo.types import PhotoAttachmentRequest

photo = PhotoAttachmentRequest.factory(token=token)
await facade.send_media(media=photo, text="Фото по токену")

Комбинирование#

Можно смешивать оба типа в одном вызове - порядок вложений сохраняется:

from maxo.types import PhotoAttachmentRequest, VideoAttachmentRequest
from maxo.utils.upload_media import BufferedInputFile

media = [
    BufferedInputFile.image(new_photo_bytes, "photo.jpg"),
    VideoAttachmentRequest.factory(token=existing_video_token),
]
await facade.send_message(text="Микс медиа", media=media)

Список доступных фасадов#

Ниже приведен список всех фасадов для различных типов событий.

class maxo.routing.facades.BaseUpdateFacade[исходный код]#

Базовые классы: SubscriptionMethodsFacade, Generic[_UpdateT]

property update: _UpdateT#
class maxo.routing.facades.BotAddedToChatFacade[исходный код]#

Базовые классы: BaseUpdateFacade[BotAddedToChat], ChatMethodsFacade

property chat_id: int#
property user: User#
property is_channel: bool#
class maxo.routing.facades.BotRemovedFromChatFacade[исходный код]#

Базовые классы: BaseUpdateFacade[BotRemovedFromChat], ChatMethodsFacade

property chat_id: int#
property user: User#
property is_channel: bool#
class maxo.routing.facades.BotStartedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[BotStarted], ChatMethodsFacade

property chat_id: int#
property user: User#
property payload: str | None | Omitted#
property user_locale: str | Omitted#
class maxo.routing.facades.BotStoppedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[BotStopped], ChatMethodsFacade

property chat_id: int#
property user: User#
property user_locale: str | Omitted#
class maxo.routing.facades.ChatTitleChangedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[ChatTitleChanged], ChatMethodsFacade

property chat_id: int#
property user: User#
property title: str#
class maxo.routing.facades.DialogClearedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[DialogCleared], ChatMethodsFacade

property chat_id: int#
property user: User#
property user_locale: str | Omitted#
class maxo.routing.facades.DialogMutedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[DialogMuted], ChatMethodsFacade

property chat_id: int#
property user: User#
property muted_until: datetime#
property user_locale: str | Omitted#
class maxo.routing.facades.DialogRemovedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[DialogRemoved], ChatMethodsFacade

property chat_id: int#
property user: User#
property user_locale: str | Omitted#
class maxo.routing.facades.DialogUnmutedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[DialogUnmuted], ChatMethodsFacade

property chat_id: int#
property user: User#
property user_locale: str | Omitted#
class maxo.routing.facades.ErrorEventFacade[исходный код]#

Базовые классы: BaseUpdateFacade[ErrorEvent[_ExceptionT, _UpdateT]], Generic[_ExceptionT, _UpdateT]

property exception: _ExceptionT#
property update: MaxoUpdate[_UpdateT]#
property error: _ExceptionT#
property event: _UpdateT#
class maxo.routing.facades.MessageCallbackFacade[исходный код]#

Базовые классы: BaseUpdateFacade[MessageCallback], CallbackMethodsFacade, MessageMethodsFacade

property message: Message#
property callback: Callback#
property user_locale: str | None | Omitted#
property callback_id: str#
property payload: str | Omitted#
property user: User#
class maxo.routing.facades.MessageCreatedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[MessageCreated], MessageMethodsFacade

property message: Message#
property text: str | None#
property user_locale: str | None | Omitted#
class maxo.routing.facades.MessageEditedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[MessageEdited], MessageMethodsFacade

property message: Message#
property text: str | None#
class maxo.routing.facades.MessageRemovedFacade[исходный код]#

Базовые классы: BaseUpdateFacade[MessageRemoved], ChatMethodsFacade

property message_id: str#
property chat_id: int#
property user_id: int#
class maxo.routing.facades.UserAddedToChatFacade[исходный код]#

Базовые классы: BaseUpdateFacade[UserAddedToChat], ChatMethodsFacade

property chat_id: int#
property user: User#
property inviter_id: int | None | Omitted#
property is_channel: bool#
class maxo.routing.facades.UserRemovedFromChatFacade[исходный код]#

Базовые классы: BaseUpdateFacade[UserRemovedFromChat], ChatMethodsFacade

property chat_id: int#
property user: User#
property admin_id: int | Omitted#
property is_channel: bool#