litegram

Лицензия MIT Статус PyPi Версия пакета PyPi Загрузки Поддерживаемые версии Python Telegram Bot API Тесты Покрытие кода

litegram — это современный и полностью асинхронный фреймворк для Telegram Bot API, написанный на Python 3.13+ с использованием litestar и httpx.

Сделайте своих ботов быстрее и мощнее!

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

Особенности

  • Асинхронность (asyncio docs, PEP 492)

  • Имеет аннотации типов (PEP 484) и может использоваться с ty

  • Поддерживает Telegram Bot API 9.3 и быстро получает обновления к последним версиям API

  • Роутер обновлений (Blueprints)

  • Имеет встроенный конечный автомат (FSM)

  • Использует мощные магические фильтры

  • Middlewares (для входящих обновлений и вызовов API)

  • Поддерживает ответы в вебхук

  • Встроенная поддержка I18n/L10n с GNU Gettext (или Fluent)

Предупреждение

Настоятельно рекомендуется иметь опыт работы с asyncio перед тем, как приступать к использованию litegram.

Если у вас есть вопросы, вы можете посетить наши сообщества в Telegram:

Простое использование

from __future__ import annotations

import asyncio
import logging
import sys
from os import getenv
from typing import TYPE_CHECKING

from litegram import Bot, Dispatcher, html
from litegram.client.default import DefaultBotProperties
from litegram.enums import ParseMode
from litegram.filters import CommandStart

if TYPE_CHECKING:
    from litegram.types import Message

# Bot token can be obtained via https://t.me/BotFather
TOKEN = getenv("BOT_TOKEN")

# All handlers should be attached to the Router (or Dispatcher)

dp = Dispatcher()


@dp.message(CommandStart())
async def command_start_handler(message: Message) -> None:
    """
    This handler receives messages with `/start` command
    """
    # Most event objects have aliases for API methods that can be called in events' context
    # For example if you want to answer to incoming message you can use `message.answer(...)` alias
    # and the target chat will be passed to :ref:`litegram.methods.send_message.SendMessage`
    # method automatically or call API method directly via
    # Bot instance: `bot.send_message(chat_id=message.chat.id, ...)`
    await message.answer(f"Hello, {html.bold(message.from_user.full_name)}!")


@dp.message()
async def echo_handler(message: Message) -> None:
    """
    Handler will forward receive a message back to the sender

    By default, message handler will handle all message types (like a text, photo, sticker etc.)
    """
    try:
        # Send a copy of the received message
        await message.send_copy(chat_id=message.chat.id)
    except TypeError:
        # But not all the types is supported to be copied so need to handle it
        await message.answer("Nice try!")


async def main() -> None:
    # Initialize Bot instance with default bot properties which will be passed to all API calls
    bot = Bot(token=TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))

    # And the run events dispatching
    await dp.start_polling(bot)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    asyncio.run(main())

Использование без диспетчера

Только взаимодействие с API, без обработки событий

from __future__ import annotations

import asyncio
from argparse import ArgumentParser

from litegram import Bot
from litegram.client.default import DefaultBotProperties
from litegram.enums import ParseMode


def create_parser() -> ArgumentParser:
    parser = ArgumentParser()
    parser.add_argument("--token", help="Telegram Bot API Token")
    parser.add_argument("--chat-id", type=int, help="Target chat id")
    parser.add_argument("--message", "-m", help="Message text to sent", default="Hello, World!")

    return parser


async def main() -> None:
    parser = create_parser()
    ns = parser.parse_args()

    token = ns.token
    chat_id = ns.chat_id
    message = ns.message

    async with Bot(
        token=token,
        default=DefaultBotProperties(
            parse_mode=ParseMode.HTML,
        ),
    ) as bot:
        await bot.send_message(chat_id=chat_id, text=message)


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

Содержание