Pyromax 🚀
Современный асинхронный Python-фреймворк для создания юзерботов в MAX Messenger.
Pyromax — современный фреймворк, вдохновлённый aiogram 3.x, который переносит привычную архитектуру Telegram-ботов в экосистему MAX Messenger.
Библиотека предоставляет всё необходимое для разработки масштабируемых проектов: Router, Dispatcher, Middlewares, FSM, Magic Filters, строгую типизацию и полностью асинхронное ядро.
✨ Основные возможности
📦 Router
Разделяйте проект на независимые модули.
⚡ Async First
Полностью асинхронное ядро на asyncio, aiohttp и websockets.
🛡 Middlewares
Перехватывайте события до и после обработки.
Подходит для:
- логирования;
- антифлуда;
- проверки прав;
- работы с БД;
- Dependency Injection;
- аналитики.
🎭 FSM (Finite State Machine)
Создавайте сложные сценарии общения:
- анкеты;
- формы;
- мастера настройки;
- регистрации;
- диалоги;
- опросы.
✨ Magic Filters
Фильтрация сообщений похожа на aiogram.
@router.message(F.text.startswith("!"))
🧩 Масштабируемая архитектура
Pyromax подходит как для небольших скриптов, так и для крупных проектов.
Используйте:
- Routers
- Nested Routers
- Middlewares
- FSM
- Custom Filters
- Dependency Injection
без необходимости переписывать архитектуру.
📦 Установка
pip install pyromax
или
uv add pyromax
🚀 Быстрый старт
import asyncio
from pyromax import MaxApi, Dispatcher
from pyromax.models import Message
# Инициализация диспетчера
dp = Dispatcher()
# Регистрация хендлера (обрабатываем все сообщения, включая свои)
@dp.message(from_me=True)
async def echo(message: Message):
await message.reply(message.text)
async def main():
# Создаем экземпляр API
api = await MaxApi()
# Запускаем бота с диспетчером
await dp.start_polling(max_api=max_api)
if __name__ == "__main__":
asyncio.run(main())
🧩 Router
Разделяйте проект по файлам.
router = Router()
@router.message(Command("ping"))
async def ping(message: Message):
await message.reply("🏓 Pong")
dp.include_router(router)
🛡 Middlewares
Используйте middleware для обработки каждого события.
Здесь ключами в data выступают объекты, которыми вы аннотируете хэндлер(по ним библиотека и понимает что нужно передать в соответствующий хэндлер). В самом простом случае ключ это класс, а значение ключа это объект этого класса
from pyromax import Dispatcher
from pyromax.dispatcher.middlewares.base import BaseMiddleware
from pyromax.dispatcher.event import MaxObject
dp = Dispatcher()
class MyDB:
"""Your DB, now its just dummy for demonstrate"""
class MyUpdateOuterMiddleware(BaseMiddleware):
async def __call__(
self,
handler: Callable[[MaxObject, dict[Any, Any]], Awaitable[Any]],
event: MaxObject,
data: dict[type[Any] | str, Any],
) -> Any:
data[MyDB] = MyDB()
return await handler(event, data)
dp.update.outer_middleware(
MyUpdateOuterMiddleware()
)
@dp.message()
async def need_to_get_db_instance(my_db: MyDB):
pass
Также в data ключами могут быть не только классы, которыми вы аннотируете параметры в хэндлерах, но и также forward ref, и обращаться в хэндлерах надо через них соответственно
class MyUpdateOuterMiddleware(BaseMiddleware):
async def __call__(
self,
handler: Callable[[MaxObject, dict[Any, Any]], Awaitable[Any]],
event: MaxObject,
data: dict[type[Any] | str, Any],
) -> Any:
data['DataBase'] = MyDB()
return await handler(event, data)
@dp.message()
async def need_to_get_db_instance(my_db: 'DataBase'):
pass
🎭 FSM
from pyromax.fsm.state import State, StatesGroup
from pyromax.fsm.context import FSMContext
from pyromax import Dispatcher, MaxApi
from pyromax.filters.command import Command
from pyromax.models import Message
class SimpleSurvey(StatesGroup):
name = State()
weather = State()
whats_up = State()
dp = Dispatcher()
@dp.message(Command('survey'))
async def start_survey(msg: Message, state: FSMContext):
await msg.reply(
text='Привет, как тебя зовут?'
)
await state.set_state(
SimpleSurvey.name
)
@dp.message(SimpleSurvey.name)
async def handle_name(msg: Message, state: FSMContext):
if not msg.text:
await msg.reply(
text='Напиши свое имя текстом!'
)
return
await state.update_data(
user_name=msg.text
)
await state.set_state(
SimpleSurvey.weather
)
await msg.answer(
text='Какая у тебя погода?'
)
@dp.message(SimpleSurvey.weather)
async def handle_weather(msg: Message, st: FSMContext):
if not msg.text:
await msg.reply(
text='Напиши свою погоду текстом!'
)
return
await st.update_data(
weather=msg.text
)
await st.set_state(
SimpleSurvey.whats_up
)
await msg.reply(
text="Как дела?"
)
@dp.message(SimpleSurvey.whats_up)
async def handle_whats_up(msg: Message, state: FSMContext):
if not msg.text:
await msg.reply(
text='Напиши свои дела текстом!'
)
return
await state.update_data(
whats_up=msg.text
)
data = await state.get_data()
await state.clear()
await msg.answer(
text=f"Тебя зовут {data.get('user_name')}, погода у тебя {data.get('weather')}, а дела у тебя {data.get('whats_up')}"
)
✨ Magic Filters
@router.message(
F.text.startswith("/"),
from_me=True
)
async def handler(message: Message):
...
💬 Форматирование сообщений
Поддерживается разметка MAX.
@dp.message(Command('lyric'), from_me=True)
async def lyric(msg: Message):
await msg.answer(text='<STRONG>They tell me, "keep it simple"</STRONG>'
'<QUOTE>I tell them, "take it slow"</QUOTE>'
'<STRIKETHROUGH>I feed a water an idea so I let it grow </STRIKETHROUGH> \n'
'<UNDERLINE>I tell them, "take it easy"</UNDERLINE> \n'
'<EMPHASIZED>They laugh and tell me, "No"</EMPHASIZED> \n'
'<LINK url="https://www.youtube.com/watch?v=9Zj0JOHJR-s">its cool...</LINK>'
)
Полная документация
📚 Roadmap
Уже реализовано
- ✅ Async Core
- ✅ Dispatcher
- ✅ Router
- ✅ Nested Routers
- ✅ Observer Pattern
- ✅ Magic Filters
- ✅ Middlewares
- ✅ FSM
- ✅ Типизация
- ✅ Formatting API
- ✅ Redis Storage
- ✅ Memory Storage
- ✅ Memory Storage
- ✅ покрытие MAX API
- ✅ Документация
В разработке
- 🚧 telemetry
- 🚧 Стабилизация работы, устойчивость, аптайм
- 🚧 Рефакторинг плохого кода
🤝 Contributing
Pull Requests приветствуются.
Если хотите предложить новую возможность — создайте Issue или откройте Pull Request.
📞 Контакты
Telegram разработчика: ТЫК
📄 License
MIT License.
Metadata
Release files for pyromax 0.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyromax-0.8.tar.gz | 138.8 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| pyromax-0.8-py3-none-any.whl | Python 3 | none | any | Details |
| pyromax-0.8-3-py3-none-any.whl | Python 3 | none | any | Details |
| pyromax-0.8-2-py3-none-any.whl | Python 3 | none | any | Details |
| pyromax-0.8-1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.0 MB
Release files / pyromax-0.8.tar.gz
| Download URL | pyromax-0.8.tar.gz |
|---|---|
| Size | 138.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5a6ef033bff73c72942185c5af4edddbcfe0817bbaa6c6b0c29cabd12344b82
|
|
BLAKE2b-256 checksum How to use checksums |
d33c510fa019fb4f43b90ee7cab95d534b4a39c13807361b5ea90dc48950aa4c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.3
|
Release files / pyromax-0.8-py3-none-any.whl
| Download URL | pyromax-0.8-py3-none-any.whl |
|---|---|
| Size | 217.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
69b3efb50f860ee6340b31c391a5ef419f98eb74b61c41ad74de5c99119f4d64
|
|
BLAKE2b-256 checksum How to use checksums |
008f30aa20b8c6250b7e900d7e8ba7d5fd759d8319c0d5bfd74d346a0fb0fa5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.3
|
Release files / pyromax-0.8-3-py3-none-any.whl
| Download URL | pyromax-0.8-3-py3-none-any.whl |
|---|---|
| Size | 221.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8c4d2a71754596df4e10cec6f0a1fcecfec0cb33dd5f2512e1d12ca40d0434e6
|
|
BLAKE2b-256 checksum How to use checksums |
eeaca1efe65098e036cc8505b6b01dce52c7a676c290d9106f62a066c6c7ba5f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.3
|
Release files / pyromax-0.8-2-py3-none-any.whl
| Download URL | pyromax-0.8-2-py3-none-any.whl |
|---|---|
| Size | 221.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ab8fca0127c8468f972d512f62b0dee07aa6148031f8b060d314576eb3f63180
|
|
BLAKE2b-256 checksum How to use checksums |
476cbd737edc88743fa5e4b2fd741dde25807c2f37ff36cf5d9d21fcf1848bb5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.3
|
Release files / pyromax-0.8-1-py3-none-any.whl
| Download URL | pyromax-0.8-1-py3-none-any.whl |
|---|---|
| Size | 221.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5147ba1ec0182c027a95a4dab17111be0e4313a8fb7523494cc16bf7a4a0cd4f
|
|
BLAKE2b-256 checksum How to use checksums |
021a5e53f48338fd096e09900768ee559bc581b7a7a313a6da3334cccdda8a4c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.3
|