Skip to main content

maxo - библиотека и асинхронный Python-фреймворк для разработки ботов MAX (max.ru) и работы с MAX Bot API

maxo - библиотека и асинхронный Python-фреймворк для разработки ботов MAX (max.ru) и работы с MAX Bot API

License Status PyPI Downloads GitHub Repo Stars GitHub Repo Forks Supported python versions Docs Tests Lint Coverage Ask DeepWiki Context7

Асинхронный Python-фреймворк для разработки ботов в MAX

Документация

Интерфейс основан на aiogram
maxo/dialogs сделано из aiogram_dialog
maxo/transport/webhook сделано из aiogram-webhook

Почему maxo?

  • Интерфейс намеренно близок к aiogram: роутеры, фильтры, мидлвари, FSM и диалоги работают так, как вы привыкли
  • Диалоги (maxo.dialogs): окна, виджеты, пагинация, календарь. Интерфейс можно посмотреть в браузере до запуска бота, а сценарии - тестировать без сети
  • Long-polling и вебхуки (aiohttp / fastapi), FSM с Redis, DI через dishka и фильтры на magic_filter
  • Методы, типы и апдейты генерируются по официальной документации MAX Bot API - меньше расхождений с платформой
  • 100% аннотаций и mypy --strict - ошибки видно в IDE, а не в проде
  • Ошибки API типизированы: можно писать except MaxBotTooManyRequestsError, а не разбирать голый HTTP-ответ
  • Российский доверенный сертификат уже вшит в HTTP-клиент, настраивать SSL для API MAX вручную не нужно
  • Асинхронность на aiohttp и unihttp, валидация данных через adaptix, документация на русском

Установка

Через pip:

pip install maxo

В pyproject.toml:

[project]
dependencies = [
    "maxo",
]

Для чего подходит maxo

  • Разработка ботов MAX на Python
  • Работа с MAX Bot API
  • long-polling и webhook для MAX
  • FSM, диалоги и inline-клавиатуры для ботов
  • Миграция с aiogram-подхода на MAX

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

Больше примеров в примерах

Эхо-бот

from maxo import Bot, Dispatcher
from maxo.types import MessageCreated

bot = Bot("TOKEN")
dp = Dispatcher()

@dp.message_created()
async def echo_handler(message: MessageCreated) -> None:
    text = message.text or "Текста нет"
    await message.answer(text)

dp.run_polling(bot)

Команды

from maxo import Bot, Dispatcher
from maxo.routing.filters import Command, DeeplinkFilter
from maxo.types import BotStarted, MessageCreated

bot = Bot("TOKEN")
dp = Dispatcher()

@dp.bot_started(DeeplinkFilter())
async def deeplink_handler(bot_started: BotStarted, deeplink: str) -> None:
    await bot_started.send_message(f"Привет! Я бот. Диплинк: {deeplink}")

@dp.bot_started()
async def start_handler(bot_started: BotStarted) -> None:
    await bot_started.send_message(f"Привет! Я бот. А ты {bot_started.user.fullname}")

@dp.message_created(Command("help"))
async def help_handler(message: MessageCreated) -> None:
    await message.send_message("За помощью обращайтесь в t.me/maxo_py")

dp.run_polling(bot)

Клавиатуры

from magic_filter import F

from maxo import Bot, Dispatcher
from maxo.integrations.magic_filter import MagicFilter
from maxo.routing.filters import CommandStart
from maxo.types import MessageCallback, MessageCreated
from maxo.utils.builders import KeyboardBuilder

bot = Bot("TOKEN")
dp = Dispatcher()

@dp.message_created(CommandStart())
async def start_handler(message: MessageCreated) -> None:
    maxo_url = "https://github.com/K1rL3s/maxo"
    keyboard = (
        KeyboardBuilder()
        .add_callback(text="Колбэк", payload="click_me")
        .add_message(text="Сообщение")
        .add_link(text="Перейти в maxo", url=maxo_url)
        .add_clipboard(text="Скопировать maxo", payload=maxo_url)
        .add_request_contact(text="Поделиться контактами")
        .add_request_geo_location(text="Поделиться геопозицией")
        .adjust(2, 2, 1, 1)
    )
    await message.answer(text="Кнопочки :3", keyboard=keyboard.build())

@dp.message_callback(MagicFilter(F.payload == "click_me"))
async def button_handler(callback: MessageCallback) -> None:
    await callback.callback_answer("Вы нажали на кнопку!")

dp.run_polling(bot)

Диалоги

Многошаговый сценарий - это окна и виджеты, переходами управляет менеджер диалога. Окна можно отрисовать в HTML-превью без запуска бота, а сценарии - тестировать без сети через maxo.dialogs.test_tools:

from maxo import Bot, Dispatcher
from maxo.dialogs import Dialog, DialogManager, StartMode, Window, setup_dialogs
from maxo.dialogs.widgets.kbd import Button
from maxo.dialogs.widgets.text import Const
from maxo.fsm import State, StatesGroup
from maxo.fsm.key_builder import DefaultKeyBuilder
from maxo.routing.filters import CommandStart
from maxo.types import MessageCallback, MessageCreated

bot = Bot("TOKEN")
# Для диалогов нужен key builder с destiny
dp = Dispatcher(key_builder=DefaultKeyBuilder(with_destiny=True))

class MainState(StatesGroup):
    main = State()

async def close_dialog(
    callback: MessageCallback,
    button: Button,
    manager: DialogManager,
) -> None:
    await manager.done()

dialog = Dialog(
    Window(
        Const("Главное меню"),
        Button(Const("Закрыть"), id="close", on_click=close_dialog),
        state=MainState.main,
    ),
)

@dp.message_created(CommandStart())
async def start_handler(
    message: MessageCreated,
    dialog_manager: DialogManager,
) -> None:
    await dialog_manager.start(MainState.main, mode=StartMode.RESET_STACK)

dp.include(dialog)
setup_dialogs(dp)

dp.run_polling(bot)

Вебхук

import logging

from aiohttp import web

from maxo import Bot, Dispatcher, Router
from maxo.enums import TextFormat
from maxo.routing.utils import collect_used_updates
from maxo.transport.webhook.adapters.aiohttp import AiohttpWebAdapter
from maxo.transport.webhook.engines import SimpleEngine, WebhookEngine
from maxo.transport.webhook.routing import StaticRouting
from maxo.transport.webhook.security import Security, StaticSecretToken
from maxo.types import BotStarted, MessageCreated

bot = Bot("TOKEN")
router = Router()

@router.bot_started()
async def start_handler(bot_started: BotStarted) -> None:
    await bot_started.send_message(
        text=f"Привет из вебхука, {bot_started.user.first_name}!",
    )

@router.message_created()
async def echo_handler(message: MessageCreated) -> None:
    await message.answer(
        text=message.message.body.html_text,
        format=TextFormat.HTML,
    )

@router.after_startup()
async def on_startup(dispatcher: Dispatcher, webhook_engine: WebhookEngine) -> None:
    await webhook_engine.set_webhook(update_types=collect_used_updates(dispatcher))

def main() -> None:
    dispatcher = Dispatcher()
    dispatcher.include(router)

    engine = SimpleEngine(
        dispatcher,
        bot,
        web_adapter=AiohttpWebAdapter(),
        routing=StaticRouting(url="https://example.com/webhook"),
        security=Security(secret_token=StaticSecretToken("pepa_pig")),
    )
    app = web.Application()
    engine.register(app)

    web.run_app(app, host="127.0.0.1", port=8080)

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)
    main()

FAQ

Что такое MAX?

MAX - российский мессенджер. У него есть открытое Bot API, для работы с которым и создан maxo.

Чем maxo отличается от aiogram?

maxo - отдельный фреймворк именно для ботов MAX, но интерфейс намеренно близок к aiogram, чтобы переход был максимально безболезненным. Диалоги (maxo.dialogs) портированы из aiogram_dialog, вебхуки (maxo.transport.webhook) - из aiogram-webhook.

Можно ли перенести бота с aiogram на maxo?

Код один в один не переносится: MAX и Telegram - разные платформы со своими типами и методами. Но подход остаётся тем же: роутеры, фильтры, хэндлеры, FSM и диалоги называются и ведут себя привычно, поэтому переучиваться почти не придётся.

Поддерживает ли maxo вебхуки?

Да. Поддерживается и long-polling, и webhook через aiohttp или fastapi - см. примеры выше.

Какой Python нужен?

Python 3.12, 3.13 или 3.14.

Где взять токен бота MAX?

На платформе для партнёров.

Как добавить FSM?

FSM встроена в maxo - есть MemoryStorage из коробки и опциональное хранилище в Redis (maxo[redis]). Подробности - в документации.

Можно ли отправлять фото, видео и файлы?

Да. maxo умеет отправлять и принимать вложения - фото, видео, аудио и документы - через InputFile (загрузка файла) или по токену уже загруженного медиа. Крупные файлы грузятся частями (resumable). Подробности - в документации.

Есть ли dependency injection?

Да, через интеграцию с dishka (maxo[dishka]). Зависимости можно прокидывать в хэндлеры, фильтры и мидлвари.

Можно ли обслуживать несколько ботов в одном приложении?

Пока частично. Готовый SimpleEngine обслуживает одного бота. Для мульти-бот сценария есть заготовки: PathRouting и QueryRouting извлекают токен бота из URL или query-параметра, а выбор бота по токену реализуется наследником WebhookEngine (метод _get_bot_from_request).

Как масштабировать бота под нагрузку?

Для продакшена используйте вебхуки: сервер MAX доставляет каждый апдейт один раз, и нагрузку можно распределить между воркерами (например, за Nginx или в Kubernetes). Long-polling для этого не подходит - при нескольких процессах с одним токеном апдейты дублируются.

Как тестировать бота без реального MAX?

Для диалогов есть maxo.dialogs.test_tools: BotClient эмулирует пользователя, MockMessageManager записывает отправленные сообщения, локаторы находят кнопки по тексту. Сценарий "клик по кнопке - смена окна - новый текст" проверяется без единого сетевого вызова. Пример - в examples/dialogs_testing.py.

maxo бесплатный? Какая лицензия?

Да, maxo - open-source под лицензией Apache 2.0. Можно использовать в том числе в коммерческих проектах.

Связь

Если у вас есть вопросы, вы можете задать их в Телеграме @maxo_py или Максе

Metadata

Release files for maxo 0.8.3

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

Source distribution (sdist)

Source distribution for maxo 0.8.3
File Size Uploaded
maxo-0.8.3.tar.gz 229.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for maxo 0.8.3
File Interpreter ABI Platform
maxo-0.8.3-py3-none-any.whl Python 3 none any Details

Total release size: 670.3 kB

Release files / maxo-0.8.3.tar.gz

Download URL maxo-0.8.3.tar.gz
Size 229.9 kB
Tags Source
SHA-256 checksum
How to use checksums
2d2fa80054680d60c20c8b072c5083b93a124ff916a6adcb71d86a1209b433f9
BLAKE2b-256 checksum
How to use checksums
c14aafb7f95e145b1482a7f7be8530251f37b3cb2dd73f80ed045c86450444f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / maxo-0.8.3-py3-none-any.whl

Download URL maxo-0.8.3-py3-none-any.whl
Size 440.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
083392148dcd4117de712165b73ee639744dec71efd77e889651663d9c224676
BLAKE2b-256 checksum
How to use checksums
8eb82baf14941bd56047a2bad84681286834b7d65d776e0f8ca56f24fd8c1bd9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.9.1

2 release files

0.9.0

2 release files

This release

0.8.3 This release

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

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