Skip to main content

telegram-bot-lite-py

Lightweight Telegram Bot API client — send messages, build keyboards, handle webhooks, all async with zero dependencies.

Pure Python ≥ 3.9. No httpx, no aiohttp, no requests. Just the stdlib.

pip install telegram-bot-lite-py

Features

  • Async-first — built on asyncio + stdlib SSL
  • Full Bot API coverage: messages, media, keyboards, commands, callbacks
  • Composable update filters (&, |, ~)
  • Long-polling and webhook modes
  • Fluent keyboard builders
  • Typed dataclasses for every API object
  • Zero third-party dependencies

Quick Start

Echo bot (long polling)

import asyncio
from telegram_bot_lite_py import TelegramBot, Dispatcher
from telegram_bot_lite_py.filters import Filters

bot = TelegramBot("YOUR_BOT_TOKEN")
dp = Dispatcher(bot)

@dp.on_command("start")
async def on_start(bot, update):
    await bot.reply(update.message, "Hello! I'm alive 🤖")

@dp.on_message(Filters.text)
async def on_text(bot, update):
    await bot.reply(update.message, f"You said: {update.message.text}")

dp.run_polling()

One-shot notification (no dispatcher needed)

import asyncio
from telegram_bot_lite_py import TelegramBot

async def notify():
    bot = TelegramBot("YOUR_BOT_TOKEN")
    await bot.send_message(CHAT_ID, "<b>Deploy complete!</b>", parse_mode="HTML")

asyncio.run(notify())

Installation

pip install telegram-bot-lite-py

Requires Python 3.9+. No other packages needed.


API Reference

TelegramBot

from telegram_bot_lite_py import TelegramBot

bot = TelegramBot(
    token="YOUR_BOT_TOKEN",
    timeout=30.0,        # per-request timeout in seconds
    parse_mode="HTML",   # default parse mode: "HTML", "Markdown", "MarkdownV2", or None
)

Sending messages

Method Description
await bot.send_message(chat_id, text, *, parse_mode, reply_markup, ...) Send a text message
await bot.reply(message, text, *, parse_mode, reply_markup) Reply to a specific message
await bot.notify(chat_id, text) Shorthand alias for send_message
await bot.send_photo(chat_id, photo, *, caption, ...) Send photo by file_id, URL, or bytes
await bot.send_document(chat_id, document, *, caption, ...) Send document
await bot.send_audio(chat_id, audio, *, caption, performer, title, ...) Send audio
await bot.send_video(chat_id, video, *, caption, duration, ...) Send video
await bot.send_location(chat_id, lat, lon, ...) Send a map pin
await bot.send_contact(chat_id, phone, first_name, ...) Send a contact
await bot.send_chat_action(chat_id, action) Show "typing…" or other indicators
await bot.forward_message(chat_id, from_chat_id, message_id) Forward a message
await bot.copy_message(chat_id, from_chat_id, message_id) Copy (without forward tag)

Editing & deleting

Method Description
await bot.edit_message_text(text, *, chat_id, message_id, ...) Edit message text
await bot.edit_message_reply_markup(*, chat_id, message_id, reply_markup) Update keyboard only
await bot.delete_message(chat_id, message_id) Delete a message

Callback queries

Method Description
await bot.answer_callback_query(callback_query_id, *, text, show_alert, url) Answer an inline button press

Chat management

Method Description
await bot.get_chat(chat_id) Fetch Chat info
await bot.leave_chat(chat_id) Leave a group/channel
await bot.ban_chat_member(chat_id, user_id, ...) Ban a user
await bot.unban_chat_member(chat_id, user_id) Unban a user
await bot.get_chat_member_count(chat_id) Member count

Bot setup

Method Description
await bot.get_me() Fetch the bot's User object
await bot.set_my_commands(commands) Set the command list shown in clients
await bot.get_my_commands() Get current commands
await bot.delete_my_commands() Remove all commands

Webhook

Method Description
await bot.set_webhook(url, *, secret_token, max_connections, ...) Register a webhook
await bot.delete_webhook(*, drop_pending_updates) Remove the webhook
await bot.get_webhook_info() Fetch current webhook status

Files

Method Description
await bot.get_file(file_id) Fetch File metadata
bot.get_file_url(file_path) Build the download URL for a File

Dispatcher

from telegram_bot_lite_py import Dispatcher

dp = Dispatcher(bot, workers=4)

Decorators

@dp.on_command("start", "help")
async def cmd_handler(bot, update): ...

@dp.on_message(Filters.text & ~Filters.command("start"))
async def text_handler(bot, update): ...

@dp.on_callback("confirm", "cancel")
async def callback_handler(bot, update): ...

@dp.on_callback(prefix="page:")
async def paginate(bot, update): ...

@dp.on_error()
async def error_handler(bot, update, exc): ...

Low-level registration

from telegram_bot_lite_py.filters import Filters

dp.add_handler(my_fn, Filters.photo, priority=10)

Running

# Blocking (runs asyncio event loop internally)
dp.run_polling(timeout=30, drop_pending=True)

# Inside an existing event loop
await dp.start_polling(timeout=30)

Filters

from telegram_bot_lite_py.filters import Filters

Filters.message          # any message update
Filters.edited_message   # edited message
Filters.callback_query   # callback query
Filters.channel_post     # channel post

Filters.text             # message has text
Filters.photo            # message has photo
Filters.document         # message has document
Filters.audio
Filters.video
Filters.location
Filters.contact
Filters.sticker

Filters.private          # private chat
Filters.group            # group or supergroup
Filters.channel          # channel

Filters.command("start", "help")
Filters.regex(r"order #\d+")
Filters.text_equals("yes", "no")
Filters.text_contains("hello")
Filters.user(123456, 789012)     # whitelist by user_id
Filters.chat(-100123456789)      # whitelist by chat_id
Filters.callback_data("ok", "cancel")
Filters.callback_prefix("page:")
Filters.custom_filter(lambda u: u.effective_user.is_premium)

Combine with &, |, ~:

private_text = Filters.text & Filters.private
not_bot      = ~Filters.user(bot_id)
media        = Filters.photo | Filters.video | Filters.document

Keyboard builders

Inline keyboards

from telegram_bot_lite_py.keyboards import InlineKeyboard, inline_keyboard

# Fluent builder
kb = (
    InlineKeyboard()
    .button("Yes", callback_data="yes")
    .button("No", callback_data="no")
    .row()
    .button("Visit", url="https://sarmkadan.com")
    .build()
)

# Compact factory
kb = inline_keyboard(
    [("Option A", "a"), ("Option B", "b")],
    [("Cancel", "cancel")],
)

await bot.send_message(chat_id, "Choose:", reply_markup=kb)

Reply keyboards

from telegram_bot_lite_py.keyboards import ReplyKeyboard, reply_keyboard

# Fluent builder
kb = (
    ReplyKeyboard(resize=True, one_time=True)
    .button("Share Location", request_location=True)
    .row()
    .button("Share Contact", request_contact=True)
    .build()
)

# Compact factory
kb = reply_keyboard(["Yes", "No"], ["Maybe", "Cancel"], resize=True)

await bot.send_message(chat_id, "Choose:", reply_markup=kb)

Remove / force reply

from telegram_bot_lite_py.keyboards import remove_keyboard, force_reply

await bot.send_message(chat_id, "Keyboard removed", reply_markup=remove_keyboard())
await bot.send_message(chat_id, "Enter your name:", reply_markup=force_reply(placeholder="Your name"))

Webhook server

import ssl
from telegram_bot_lite_py import TelegramBot, Dispatcher, WebhookServer

bot = TelegramBot("YOUR_BOT_TOKEN")
dp  = Dispatcher(bot)

@dp.on_command("start")
async def start(bot, update):
    await bot.reply(update.message, "Hello from webhook!")

# Optional TLS termination
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain("cert.pem", "key.pem")

server = WebhookServer(
    dp,
    host="0.0.0.0",
    port=8443,
    path="/webhook",
    secret_token="my-secret",
    ssl_context=ctx,
)

# Register webhook then start
import asyncio

async def main():
    await bot.set_webhook(
        "https://your-domain.com/webhook",
        secret_token="my-secret",
        max_connections=40,
    )
    await server.start()
    # keep running
    await asyncio.Event().wait()

asyncio.run(main())

Types

All Telegram API objects are plain Python dataclasses.

from telegram_bot_lite_py import Update, Message, User, Chat, CallbackQuery

update: Update
update.update_id
update.message           # Message | None
update.edited_message    # Message | None
update.callback_query    # CallbackQuery | None
update.effective_message # first non-None of message / edited_message / channel_post
update.effective_chat    # Chat | None
update.effective_user    # User | None

message: Message
message.message_id
message.chat             # Chat
message.from_user        # User | None
message.text             # str | None
message.content_type     # "text" | "photo" | "document" | ...
message.get_command()    # "/start" | None
message.get_args()       # "arg1 arg2" – everything after the command

user: User
user.id
user.full_name           # "First Last"
user.mention             # "@username" or full name

chat: Chat
chat.id
chat.type                # "private" | "group" | "supergroup" | "channel"
chat.is_private          # bool
chat.is_group            # bool
chat.display_name        # title or first_name

Error handling

from telegram_bot_lite_py.exceptions import (
    TelegramAPIError,
    RetryAfterError,
    ForbiddenError,
    NetworkError,
)

@dp.on_error()
async def handle_error(bot, update, exc):
    if isinstance(exc, RetryAfterError):
        print(f"Flood limit. Retry after {exc.retry_after}s")
    elif isinstance(exc, ForbiddenError):
        print("Bot was blocked by user")
    elif isinstance(exc, NetworkError):
        print(f"Network problem: {exc}")
    else:
        print(f"Unhandled error: {exc}")

Examples

Notification bot

import asyncio
from telegram_bot_lite_py import TelegramBot

async def alert(chat_id: int, message: str):
    bot = TelegramBot("YOUR_TOKEN")
    await bot.send_message(chat_id, f"<b>Alert</b>\n{message}", parse_mode="HTML")

asyncio.run(alert(-100123456789, "Server CPU above 90%"))

Paginated inline buttons

@dp.on_command("list")
async def cmd_list(bot, update):
    kb = inline_keyboard(
        [("Item 1", "item:1"), ("Item 2", "item:2")],
        [("< Prev", "page:0"), ("Next >", "page:2")],
    )
    await bot.reply(update.message, "Choose an item:", reply_markup=kb)

@dp.on_callback(prefix="item:")
async def on_item(bot, update):
    item_id = update.callback_query.data.split(":")[1]
    await bot.answer_callback_query(update.callback_query.id, text=f"Selected item {item_id}")

@dp.on_callback(prefix="page:")
async def on_page(bot, update):
    page = int(update.callback_query.data.split(":")[1])
    await bot.answer_callback_query(update.callback_query.id, text=f"Page {page}")

Admin-only commands

ADMIN_IDS = [123456789]

@dp.on_command("ban", priority=100)
async def cmd_ban(bot, update):
    if update.effective_user.id not in ADMIN_IDS:
        await bot.reply(update.message, "Access denied.")
        return
    # ... ban logic

License

MIT — see LICENSE.

© 2024 Vladyslav Zaiets — sarmkadan.com

Metadata

Release files for telegram-bot-lite-py 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for telegram-bot-lite-py 1.0.0
File Size Uploaded
telegram_bot_lite_py-1.0.0.tar.gz 21.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for telegram-bot-lite-py 1.0.0
File Interpreter ABI Platform
telegram_bot_lite_py-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.6 kB

Release files / telegram_bot_lite_py-1.0.0.tar.gz

Download URL telegram_bot_lite_py-1.0.0.tar.gz
Size 21.8 kB
Tags Source
SHA-256 checksum
How to use checksums
3b400fb1c6691aa237beca3e9bfa7367779786f59f76949e3375c0f0acfaaa2f
BLAKE2b-256 checksum
How to use checksums
2b7523478ed4b371a0ad7d6e16c0ebb60d421c4e9db8d08366eb3d73ab29c24e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / telegram_bot_lite_py-1.0.0-py3-none-any.whl

Download URL telegram_bot_lite_py-1.0.0-py3-none-any.whl
Size 26.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a21fb98e03c329b79bc7e9f1ea4d917939b0a003540213331e6352e89531c28d
BLAKE2b-256 checksum
How to use checksums
82a09587feec6002becec1ce54b068be82697f0426bcb47fb151b7caeee1fd56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page