Metadata-Version: 2.4
Name: maxapi
Version: 1.2.3
Summary: Библиотека для разработки чат-ботов с помощью API мессенджера MAX
Keywords: max,api,bot
Author: Denis
Author-email: Denis <bestloveapples@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Dist: aiohttp>=3.13,<4
Requires-Dist: backoff>=2.2,<3
Requires-Dist: magic-filter>=1.0.4,<2
Requires-Dist: pydantic>=2.12,<3
Requires-Dist: aiofiles>=24.1,<26
Requires-Dist: puremagic>=1.30,<2
Requires-Dist: fastapi>=0.103.0,<1 ; extra == 'fastapi'
Requires-Dist: uvicorn>=0.15.0,<1 ; extra == 'fastapi'
Requires-Dist: litestar>=2.0.0,<3 ; python_full_version < '3.12' and extra == 'litestar'
Requires-Dist: litestar>=2.3.0,<3 ; python_full_version >= '3.12' and extra == 'litestar'
Requires-Dist: uvicorn>=0.15.0,<1 ; extra == 'litestar'
Requires-Dist: maxapi[fastapi] ; extra == 'webhook'
Requires-Python: >=3.10
Project-URL: Homepage, https://github.com/love-apples/maxapi
Project-URL: Documentation, https://love-apples.github.io/maxapi/
Project-URL: Repository, https://github.com/love-apples/maxapi
Project-URL: Issues, https://github.com/love-apples/maxapi/issues
Project-URL: Changelog, https://github.com/love-apples/maxapi/releases
Provides-Extra: fastapi
Provides-Extra: litestar
Provides-Extra: webhook
Description-Content-Type: text/markdown

<p align="center">
  <a href="https://github.com/love-apples/maxapi"><img src="https://raw.githubusercontent.com/love-apples/maxapi/main/logo.png" alt="MaxAPI"></a>
</p>


<p align="center">
<a href='https://max.ru/join/IPAok63C3vFqbWTFdutMUtjmrAkGqO56YeAN7iyDfc8'>MAX Чат</a> •
<a href='https://t.me/maxapi_github'>TG Чат</a>
</p>

<p align="center">
<a href='https://pypi.org/project/maxapi/'>
  <img src='https://img.shields.io/pypi/v/maxapi.svg' alt='PyPI version'></a>
  <img src="https://static.pepy.tech/badge/maxapi/month" alt="PyPI downloads per month">
<a href='https://pypi.org/project/maxapi/'>
  <img src='https://img.shields.io/pypi/pyversions/maxapi.svg' alt='Python Version'></a>
<a href='https://codecov.io/gh/love-apples/maxapi'>
  <img src='https://img.shields.io/codecov/c/github/love-apples/maxapi.svg' alt='Coverage'></a>
<a href='https://github.com/love-apples/maxapi/actions/workflows/tests.yml'>
  <img src='https://github.com/love-apples/maxapi/actions/workflows/tests.yml/badge.svg' alt='Tests'></a>
<a href='https://github.com/love-apples/maxapi/actions/workflows/lint.yml'>
  <img src='https://github.com/love-apples/maxapi/actions/workflows/lint.yml/badge.svg' alt='Lint'></a>
<a href='https://github.com/love-apples/maxapi/actions/workflows/mypy.yml'>
  <img src='https://github.com/love-apples/maxapi/actions/workflows/mypy.yml/badge.svg' alt='Mypy'></a>
<a href='https://github.com/love-apples/maxapi/actions/workflows/package.yml'>
  <img src='https://github.com/love-apples/maxapi/actions/workflows/package.yml/badge.svg' alt='Package'></a>
<a href='https://github.com/love-apples/maxapi/actions/workflows/codeql.yml'>
  <img src='https://github.com/love-apples/maxapi/actions/workflows/codeql.yml/badge.svg' alt='CodeQL'></a>
<a href='https://github.com/love-apples/maxapi/actions/workflows/docs.yml'>
  <img src='https://github.com/love-apples/maxapi/actions/workflows/docs.yml/badge.svg' alt='Docs'></a>
<a href='https://github.com/love-apples/maxapi/blob/main/LICENSE'>
  <img src='https://img.shields.io/github/license/love-apples/maxapi.svg' alt='License'></a>
</p>


## Документация и ссылки

- Документация maxapi: https://love-apples.github.io/maxapi/
- Официальная документация MAX Bot API: https://dev.max.ru/docs-api/
- Примеры ботов: https://love-apples.github.io/maxapi/examples/

## Возможности

- Асинхронный `Bot` с тонкими обёртками над методами MAX Bot API.
- `Dispatcher`, `Router`, фильтры, `F` и middleware в стиле aiogram.
- FSM-контекст через `MemoryContext` и `RedisContext`.
- Polling и webhook через aiohttp, FastAPI или Litestar.
- Работа с медиа: загрузка, отправка и скачивание файлов.
- Inline-кнопки, callbacks и типизированные callback payloads.

## Установка из PyPI

Стабильная версия

```bash
pip install maxapi
```

Если проект управляется через uv:

```bash
uv add maxapi
```

## Установка из GitHub

Свежая версия, возможны баги. Рекомендуется только для ознакомления с новыми коммитами.

```bash
pip install git+https://github.com/love-apples/maxapi.git
```


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

Если вы тестируете бота в чате - не забудьте дать ему права администратора!

### Запуск Polling

> ⚠️ Long Polling ограничен по скорости и сроку хранения событий и **не
> подходит для production-окружения**. Для боевого окружения используйте
> [Webhook](#запуск-webhook).

Если у бота есть активные Webhook-подписки, события не будут приходить
через `start_polling`. Перед переходом на polling удалите подписки через
`await bot.delete_webhook()`.

```python
import asyncio
import logging

from maxapi import Bot, Dispatcher, F
from maxapi.filters.command import CommandStart
from maxapi.types import BotStarted, MessageCreated

logging.basicConfig(level=logging.INFO)

# Внесите токен бота в переменную окружения MAX_BOT_TOKEN
# Не забудьте загрузить переменные из .env в os.environ
# или задайте его аргументом в Bot(token='...')
bot = Bot()
dp = Dispatcher()


# Ответ бота при нажатии на кнопку "Начать"
@dp.bot_started()
async def bot_started(event: BotStarted):
    await bot.send_message(
        chat_id=event.chat_id, text="Привет! Отправь мне /start"
    )


# Ответ бота на команду /start
@dp.message_created(CommandStart())
async def hello(event: MessageCreated):
    await event.message.answer("Пример чат-бота для MAX 💙")


@dp.message_created(F.message.body.text)
async def echo(event: MessageCreated):
    await event.message.answer(event.message.body.text)


async def main():
    await dp.start_polling(bot)


if __name__ == "__main__":
    asyncio.run(main())
```

### Запуск Webhook

> 🔒 С 25.05.2026 прекращается поддержка получения вебхуков по HTTP и
> самоподписных сертификатов. Используйте **HTTPS** и сертификаты, выданные
> доверенным центром сертификации.

Webhook работает «из коробки» — aiohttp уже включён в базовый пакет:

```bash
pip install maxapi
```

Для проекта на uv:

```bash
uv add maxapi
```

Ниже простой запуск через aiohttp. Для production-интеграции с FastAPI,
подпиской webhook и проверкой `secret` смотрите
[пример 09_webhook_bot.py](examples/09_webhook_bot.py).

```python
import asyncio
import logging

from maxapi import Bot, Dispatcher
from maxapi.filters.command import CommandStart
from maxapi.types import MessageCreated

logging.basicConfig(level=logging.INFO)

bot = Bot()
dp = Dispatcher()


# Команда /start боту
@dp.message_created(CommandStart())
async def hello(event: MessageCreated):
    await event.message.answer("Привет из вебхука!")


async def main():
    await dp.handle_webhook(
        bot=bot,
        host="0.0.0.0",
        port=8080,
    )


if __name__ == "__main__":
    asyncio.run(main())
```

#### FastAPI и Litestar

Если хотите использовать FastAPI или Litestar вместо aiohttp, установите
нужную опциональную зависимость через pip:

```bash
pip install "maxapi[fastapi]"
pip install "maxapi[litestar]"
```

Или через uv:

```bash
uv add "maxapi[fastapi]"
uv add "maxapi[litestar]"
```

Пример запуска через **FastAPI**:

```python
import asyncio
import uvicorn
from fastapi import FastAPI
from maxapi.webhook.fastapi import FastAPIMaxWebhook


async def main():
    webhook = FastAPIMaxWebhook(dp=dp, bot=bot)
    app = FastAPI(lifespan=webhook.lifespan)
    webhook.setup(app, path="/webhook")
    await uvicorn.Server(
        uvicorn.Config(app, host="0.0.0.0", port=8080)
    ).serve()


asyncio.run(main())
```

Пример запуска через **Litestar**:

```python
import asyncio
import uvicorn
from maxapi.webhook.litestar import LitestarMaxWebhook


async def main():
    webhook = LitestarMaxWebhook(dp=dp, bot=bot)
    app = webhook.create_app(path="/webhook")
    await uvicorn.Server(
        uvicorn.Config(app, host="0.0.0.0", port=8080)
    ).serve()


asyncio.run(main())
```

## Разработка и релиз

- Окружение: `uv sync`. Перед PR: `make run-test` (ruff, mypy, pytest) и `make check-ci`
  (сборка пакета, actionlint, zizmor). Подробности и соглашения — в [AGENTS.md](AGENTS.md).
- После правки зависимостей в `pyproject.toml` обновите lock: `uv lock`. CI ставит
  инструменты с `--locked` и упадёт на рассинхроне.
- Релиз: `uv version --bump patch` (или `minor`/`major`) обновляет версию в `pyproject.toml`
  и `uv.lock` вместе; после мержа в `main` публикация на PyPI, тег и GitHub Release
  создаются автоматически, если такой версии на PyPI ещё нет. Если шаг после загрузки
  на PyPI упал, помогает «Re-run failed jobs» того же run: шаги тега и release
  идемпотентны. Свежий запуск увидит версию на PyPI и ничего не сделает.
