Асинхронный фреймворк для MAX Bot API
Project description
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 — деплой в один клик, мониторинг, автозапуск. |
Лицензия
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d52934bb6d734c3d77daccc8b7374dcd6785ae47326d8649464f83cd6e2251f
|
|
| MD5 |
3f7060729cf0515215b9800c79f5e210
|
|
| BLAKE2b-256 |
387e15ddeb90c56fc5a67a0bed3aca222b02b3fee8db4f57e2a8cc547c8ea613
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3ca7523c1cd4bde9860ccbd9b4c55f152d2586323cb1b5fbf1b59f6e4a09218
|
|
| MD5 |
034d20da88f8a98057767d572b92b7a0
|
|
| BLAKE2b-256 |
d5f90e2e8bca3f6fa86e808d10788543cf0080171eb9c54d76d875b7ac9fab6c
|