Skip to main content

maxapi-lite

PyPI Python CI

Легковесный асинхронный клиент MAX Bot API, совместимый с aiohttp 3.8.x.

Пакет нужен, когда в проекте уже зафиксирован старый aiohttp — например, рядом живёт aiogram 2.x (aiohttp<3.9), а официальный клиент maxapi требует aiohttp>=3.12. Зависимости — только aiohttp>=3.8 и pydantic>=2.

Lightweight async client for the MAX messenger Bot API that works with aiohttp 3.8, so it can share an environment with aiogram 2.x.

Установка

pip install maxapi-lite

Быстрый старт

import asyncio
from maxapi_lite import Bot, ParseMode


async def main():
    bot = Bot(token="YOUR_MAX_TOKEN", parse_mode=ParseMode.HTML)  # или переменная окружения MAX_BOT_TOKEN

    # Кнопка-ссылка
    kb_attachment = bot.build_link_button_attachment(
        text="Открыть MiniApp",
        url="https://example.com/app?startapp=123",
    )

    # Отправка фото + кнопки
    result = await bot.send_message_with_media(
        chat_id=-1,  # Демонстрационный ID — замените на ID своего чата
        text="<b>Розыгрыш</b>",
        media_type="photo",
        file_path="banner.jpg",  # или media_url="https://..."
        attachments=[kb_attachment],
    )

    # Извлечение mid и закрепление
    mid = bot.extract_message_id(result)
    if mid:
        await bot.pin_chat_message(chat_id=-1, message_id=mid)

    await bot.close_session()


asyncio.run(main())

Long polling

marker = None
while True:
    data = await bot.get_updates(timeout=30, marker=marker)
    for update in data.get("updates", []):
        ...
    marker = data.get("marker", marker)

Можно передать types=["message_created", "message_callback"]. Библиотека оставляет HTTP-таймауту запас не менее 10 секунд относительно timeout поллинга; явно отключённые ограничения HTTP не включаются обратно. Допустимый timeout — 0–90, limit — 1–1000. MAX рекомендует использовать Webhook для production: Long Polling ограничен скоростью и сроком хранения событий (документация).

Подключение и TLS

По умолчанию запросы идут на https://platform-api2.max.ru. Для другого сервера передайте base_url. Настройки доступны как в Bot, так и в MaxApiClient:

import ssl
import aiohttp
from maxapi_lite import Bot

tls = ssl.create_default_context()
# При необходимости добавьте доверенный сертификат в окружении приложения:
# tls.load_verify_locations(cafile="/path/to/trusted-ca.pem")

bot = Bot(
    ssl_context=tls,  # токен берётся из MAX_BOT_TOKEN
    timeout=aiohttp.ClientTimeout(total=60),
    transfer_timeout=aiohttp.ClientTimeout(
        total=None, connect=30, sock_connect=30, sock_read=120,
    ),
)

API по умолчанию использует total=300. У upload/download нет общего ограничения времени, но по умолчанию установлены таймауты соединения 30 с и чтения 120 с. Вместо ssl_context можно передать connector=aiohttp.TCPConnector(ssl=tls); одновременно эти параметры передавать нельзя. Внешний connector закрывает вызывающий код. Собственные сессии и connector библиотека закрывает через await bot.close_session(); вызывайте его в finally.

Входящие файлы и видео

Извлекайте URL из входящего события и передавайте его в download_file:

from maxapi_lite import Bot

async def save_incoming_video(bot: Bot, update: dict, destination: str) -> int:
    for attachment in bot.extract_attachments(update):
        if attachment.get("type") == "video":
            url = (attachment.get("payload") or {}).get("url")
            if url:
                return await bot.download_file(url, destination)
    return 0

download_file(url, dest_path, *, chunk_size=1<<20, max_retries=3) возвращает число сохранённых байтов. Скачивание идёт чанками через отдельную сессию без токена бота, включая переходы по редиректам. max_retries=3 — до трёх повторов после первой попытки. При обрыве выполняется докачка через Range/If-Range, если сервер предоставил сильный ETag или Last-Modified; без валидатора скачивание начинается заново. Ответ 200 вместо 206 также перезаписывает временный файл с начала. Размер сверяется с Content-Length/Content-Range, когда они доступны.

Существующий файл назначения заменяется атомарно после успешного скачивания. При ошибке или отмене временный файл удаляется; между вызовами докачка не сохраняется. Родительский каталог назначения должен существовать.

Для скачивания по готовому payload.url токен видео не нужен. await bot.get_video(video_token) отдельно получает метаданные через API; urls в ответе может быть None.

По наблюдениям, приведённым в задании ClipWizard: входящее video перекодируется MAX и URL живёт около 24 часов; file сохраняет исходные байты и URL живёт около 30 дней; изображение может возвращаться в webp. Это наблюдения, а не гарантии SDK: скачивайте входящие файлы своевременно. Ошибка HTTP 403 возвращается без автоматических повторов; приложение может запросить свежую ссылку через MAX API, если такая возможность доступна для вложения.

Загрузка и отправка результата

await bot.send_message_with_media(
    chat_id=-1,  # замените на свой ID
    media_type="video",
    file_path="result.mp4",
    text="Видео готово",
    wait_attachments=True,
    attachment_wait_timeout=60,
)

Файл передаётся потоком в multipart-поле data. Для video/audio библиотека сохраняет токен из ответа /uploads, если сервер заливки не вернул собственный. Токен вложения используется при отправке сообщения; передавать его вручную при загрузке локального файла не требуется.

При wait_attachments=True отправка или редактирование повторяется только после ошибки attachment.not.ready. Паузы растут 1, 2, 4, 8, 16 с, затем остаются 16 с; запросы и паузы ограничены общим бюджетом attachment_wait_timeout (60 с по умолчанию). Эти параметры работают у send_message, edit_message и обоих методов *_with_media. По умолчанию ожидание выключено. Истечение бюджета после определённого ответа not.ready даёт AttachmentNotReady; таймаут запроса с неизвестным результатом остаётся asyncio.TimeoutError.

Размер локального файла проверяется до запроса /uploads:

Тип Максимум в байтах
image 50 000 000
video 250 000 000
audio 256 000 000
file 4 000 000 000

Используются консервативные десятичные МБ/ГБ. При превышении возникает FileTooLarge с полями size и limit. MAX также ограничивает изображения 7680×7680 px и аудио 60 минутами; поддерживает MP4/MOV/MKV/WEBM для video. Проверка содержимого, разрешения и длительности выполняется сервером; локально библиотека не декодирует медиа (лимиты MAX). Resumable upload пока не реализован; после обрыва заливку нужно запускать заново.

Клавиатуры и callback

from maxapi_lite import CallbackButton, LinkButton

keyboard = bot.build_keyboard([
    [CallbackButton(text="Обработать", payload="process")],
    [LinkButton(text="Открыть сайт", url="https://example.com")],
])
await bot.send_message(chat_id=-1, text="Выберите действие", attachments=[keyboard])
await bot.send_callback(
    callback_id="CALLBACK_ID_FROM_UPDATE",
    notification="Готово",
    message={"text": "Обработка запущена", "attachments": []},
)

Модели кнопок сериализуются с обязательным полем type. build_keyboard принимает ряды моделей или словарей и возвращает одно вложение inline_keyboard. send_callback может отправлять уведомление, обновлённое сообщение или оба.

Ошибки и повторы

MaxApiError.code — числовой HTTP status, MaxApiError.api_code — строковый код ошибки MAX, если он есть. FileTooLarge, AttachmentNotReady, RateLimited наследуют MaxApiError; InvalidToken сохраняет прежнее поведение.

При HTTP 429 возникает RateLimited; поле retry_after содержит задержку в секундах из Retry-After либо None. 429 автоматически не повторяется. MAX указывает общий предел 30 rps, а для /answers — не более двух ответов в секунду в один диалог/чат/канал; очередь и регулирование частоты остаются в приложении (uploads, answers).

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

Методы Bot

Группа Методы
Бот и обновления get_me, get_updates, extract_attachments
Сообщения send_message, edit_message, delete_message, get_message
Медиа upload_file, download_file, get_video, create_media_attachment, send_message_with_media, edit_message_with_media
Закрепление pin_chat_message, pin_from_response, unpin_chat_message
Чаты get_chat_by_id, get_chat_member, get_chat_members_batch, get_list_admin_chat
Callback send_callback
Утилиты extract_message_id, build_keyboard, build_link_button_attachment

Методы возвращают «сырые» dict из ответа API. Ошибки API поднимаются как MaxApiError (с полем code), ошибка авторизации — как InvalidToken.

Поддерживаемые media_type

  • photo, animation, image → загрузка как image
  • video
  • audio
  • document, file

Примечания

  • chat_id / user_id передаются query-параметрами, как требует MAX API.
  • edit_message(..., attachments=[]) явно очищает вложения; attachments=None оставляет их как есть.
  • Формат (parse_mode) применяется к редактированию только если передан text.
  • Для upload используется multipart-поле data.

Разработка

pip install -e ".[test]"
pytest

Релиз: поднять __version__ в src/maxapi_lite/__init__.py, дополнить CHANGELOG.md, создать GitHub Release с тегом vX.Y.Z — workflow publish.yml соберёт пакет и опубликует его на PyPI.

Лицензия

MIT

Metadata

Release files for maxapi-lite 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for maxapi-lite 0.3.0
File Size Uploaded Provenance
maxapi_lite-0.3.0.tar.gz 26.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for maxapi-lite 0.3.0
File Interpreter ABI Platform
maxapi_lite-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 47.0 kB

Release files / maxapi_lite-0.3.0.tar.gz

Download URL maxapi_lite-0.3.0.tar.gz
Size 26.0 kB
Tags Source
SHA-256 checksum
How to use checksums
80eb2560d91ef7f0abfe03afc9eb2e78f47e9362f997d06eab38ac96d066e797
BLAKE2b-256 checksum
How to use checksums
22dc15ad198668942e7d618eb79617eccbcdb9ee6b32351965fda5b7558ae62b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / maxapi_lite-0.3.0-py3-none-any.whl

Download URL maxapi_lite-0.3.0-py3-none-any.whl
Size 21.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
db342793dfc54cc0e5217f77a332c2dbfca7318242c3b82a50fee2351f3a15b5
BLAKE2b-256 checksum
How to use checksums
0c11c3e3b51d62018ca463f78284f57dd5dba7c28a769ee00e5e713d0d4d288b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Security for maxapi-lite 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for maxapi_lite-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page