Skip to main content

Асинхронный фреймворк для MAX Bot API

Project description

PyPI version Python versions Monthly downloads License: MIT mypy strict

maxio

Асинхронный Python-фреймворк для MAX Bot API
с внедрением зависимостей по аннотациям типов.


Объявляйте в сигнатуре хэндлера то, что нужно, — фреймворк подставит из контекста апдейта сам:

@app.message(Command("help"))
async def help_cmd(message: Message) -> None:
    await message.answer("Это бот на фреймворке maxio!")

Никаких context["bot"], никакого middleware_data. Просто типы.

Установка

pip install maxio

Python 3.10+, зависимости: httpx + pydantic v2.

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

Получите токен у @MasterBot:

import os
from maxio import MaxBot, Message, Callback, Command, InlineKeyboard, Update, Bot
from maxio.keyboards import Button

app = MaxBot(token=os.environ["MAX_TOKEN"])


# Синяя кнопка Start шлёт событие bot_started (без message), а не /start.
@app.bot_started()
async def on_start(update: Update, bot: Bot):
    kb = InlineKeyboard().row(Button.callback("Нажми меня", "ping"))
    await bot.send_message("Привет! Я готов к работе.", chat_id=update.chat_id, keyboard=kb)


@app.message(Command("help"))
async def help_cmd(message: Message):
    await message.answer("Это бот на фреймворке maxio!")


@app.callback()
async def on_ping(callback: Callback):
    await callback.answer(notification="Понг!")        # всплывашка на кнопке
    if callback.message:
        await callback.message.answer("Ты нажал кнопку!")  # новое сообщение в чат


@app.message()
async def echo(message: Message):
    await message.reply(message.text or "")


if __name__ == "__main__":
    app.run()
MAX_TOKEN=<ваш_токен> python bot.py

Внедрение зависимостей

Тип Когда доступен
Message message_created, message_edited, callback
Callback message_callback
User отправитель/инициатор события
Chat message_chat_created
Update всегда (сырой апдейт)
Bot всегда (HTTP-клиент, прямой доступ к API)

Несовместимый тип → понятная ошибка MaxError с описанием проблемы.

Декораторы событий

Имена декораторов совпадают с типами событий MAX Bot API.

Декоратор Тип события Когда срабатывает
@app.message() message_created пришло новое сообщение от пользователя
@app.message_edited() message_edited пользователь отредактировал своё сообщение
@app.callback() message_callback нажата inline-кнопка (callback) под сообщением
@app.bot_started() bot_started пользователь запустил бота — синяя кнопка Start
@app.event(*types) любые подписка на произвольные типы апдейтов (или все — без аргументов)

Несколько хэндлеров — первый подходящий выигрывает (first-match-wins).

Чем message отличается от bot_started

Это частая путаница. Синяя кнопка Start в MAX не отправляет текст /start — она шлёт отдельное событие bot_started, в котором нет объекта Message (есть chat_id, user и опциональный payload из диплинка). Поэтому:

  • хэндлер @app.message(Command("start")) ловит только ручной ввод /start;
  • нажатие кнопки Start ловится через @app.bot_started().

Если нужно, чтобы и кнопка, и команда здоровались одинаково — заведите оба обработчика. Внутри bot_started нет Message, поэтому отвечать надо через Bot, указывая chat_id:

@app.bot_started()
async def on_start(update: Update, bot: Bot):
    await bot.send_message("Привет! Нажми кнопку ниже.", chat_id=update.chat_id)


@app.message(Command("start"))           # ручной ввод /start
async def start_cmd(message: Message):
    await message.answer("Привет! Нажми кнопку ниже.")

callback — нажатия inline-кнопок

Срабатывает, когда пользователь жмёт кнопку, созданную через Button.callback(text, payload). В обработчике доступен Callback; отвечать на нажатие нужно callback.answer(...), иначе у пользователя останется «крутилка» на кнопке. Исходное сообщение с кнопкой лежит в callback.message — у него есть привычные answer() / reply() для отправки в тот же чат.

@app.callback(CallbackPayload("buy"))    # фильтр по payload кнопки
async def buy(callback: Callback):
    await callback.answer(notification="Покупка оформлена")   # всплывашка на кнопке
    if callback.message:
        await callback.message.answer("Спасибо за заказ!")    # новое сообщение в чат

Фильтры

from maxio import Command, CallbackPayload

@app.message(Command("help"))
async def help_cmd(message: Message): ...

@app.callback(CallbackPayload("buy"))
async def buy(callback: Callback): ...

# Произвольный callable — тоже фильтр
@app.message(lambda u: u.message and len(u.message.text or "") > 100)
async def long_message(message: Message): ...

Inline-клавиатуры

from maxio import InlineKeyboard
from maxio.keyboards import Button

kb = (
    InlineKeyboard()
    .row(Button.callback("Да", "yes"), Button.callback("Нет", "no"))
    .row(Button.link("Сайт", "https://example.com"))
)
await message.answer("Выберите:", keyboard=kb)

Методы API

@app.message()
async def handler(message: Message, bot: Bot):
    me = await bot.get_me()
    await bot.send_message(chat_id=message.recipient.chat_id, text=f"Я — {me.name}")
    await bot.edit_message(message_id=message.message_id, text="Обновлено")
    await bot.delete_message(message_id=message.message_id)
    chats = await bot.get_chats()

Возможности

  • Long polling с автоматическим переподключением
  • HTTP-клиент: get_me, send_message, edit_message, delete_message, get_messages, get_chats, answer_callback, get_updates
  • Декораторы: message, message_edited, callback, bot_started, event
  • DI по аннотациям типов — работает из коробки, без Depends()
  • Фильтры: Command, CallbackPayload, любой Callable
  • Inline-клавиатуры: callback / link / request_geo_location
  • Сахар: message.answer(), message.reply(), callback.answer(), callback.message.answer()
  • Pydantic v2, py.typed, mypy --strict

Спонсоры

sudoteach.com

Генеральный спонсор.
Онлайн-школа программирования — там есть курс «Боты на maxio»: от установки до продакшна.
bothost.ru

Официальный партнёр.
Хостинг для ботов MAX и Telegram — деплой в один клик, мониторинг, автозапуск.

Лицензия

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

maxio-0.2.0.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

maxio-0.2.0-py3-none-any.whl (21.9 kB view details)

Uploaded Python 3

File details

Details for the file maxio-0.2.0.tar.gz.

File metadata

  • Download URL: maxio-0.2.0.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for maxio-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5d52934bb6d734c3d77daccc8b7374dcd6785ae47326d8649464f83cd6e2251f
MD5 3f7060729cf0515215b9800c79f5e210
BLAKE2b-256 387e15ddeb90c56fc5a67a0bed3aca222b02b3fee8db4f57e2a8cc547c8ea613

See more details on using hashes here.

File details

Details for the file maxio-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: maxio-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 21.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for maxio-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e3ca7523c1cd4bde9860ccbd9b4c55f152d2586323cb1b5fbf1b59f6e4a09218
MD5 034d20da88f8a98057767d572b92b7a0
BLAKE2b-256 d5f90e2e8bca3f6fa86e808d10788543cf0080171eb9c54d76d875b7ac9fab6c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page