Skip to main content

Minimal Python wrapper for the Telegram Bot API; one Event, one router, sync and async.

Project description

Shingram

Channel Documentation

Minimal Python wrapper for the Telegram Bot API. Future-proof: new API methods work without library updates. Dual mode: same code works sync or async. All updates normalized to a single Event object — no dozens of classes to learn.

Features

  • Zero hardcoding — Call any Telegram method; new API features work immediately
  • One Event type — Every update (message, callback, inline, etc.) has the same shape
  • Sync & Async — Use bot.run() or bot.run_async() with the same handlers
  • ~1,200 lines — Lightweight, readable, easy to contribute

Installation

pip install shingram

Documentation

Full documentation: nouzumoto.github.io/shingram

Quick Start

from shingram import Bot

bot = Bot("YOUR_BOT_TOKEN")

@bot.on("command:start")
def handle_start(event):
    bot.send_message(chat_id=event.chat_id, text="Hello!")

@bot.on("message")
def handle_message(event):
    bot.send_message(chat_id=event.chat_id, text=f"You wrote: {event.text}")

bot.run()

Event types

  • Commands: command:start, command:help, etc. Use command to catch all commands
  • Messages: message for text messages
  • Edited messages: edited_message for edited text messages
  • Channel posts: channel_post and edited_channel_post
  • Inline queries: inline_query for inline search queries
  • Callback queries: callback for inline button clicks
  • Join/Leave events: join and leave for group membership changes
  • Poll updates: poll and poll_answer for poll-related events
  • Chat member updates: chat_member and my_chat_member
  • Chat join requests: chat_join_request
  • Business messages: business_message, edited_business_message, business_connection
  • Message reactions: message_reaction and message_reaction_count
  • Chat boosts: chat_boost and removed_chat_boost
  • Shipping and payment: shipping_query, pre_checkout_query
  • Chosen inline results: chosen_inline_result

Handlers always get the same Event; the field that varies is type (and name for commands/callbacks).

Event fields

@dataclass
class Event:
    type: str                    # Event type: "command", "message", "callback", etc.
    name: str                    # Event name: "start" for commands, "" for others
    chat_id: int                 # Chat ID (0 if not applicable)
    user_id: int                 # User ID (0 if not applicable)
    text: str                    # Message text or callback data
    raw: dict                    # Complete raw data from Telegram API
    reply_to: Optional[int]      # ID of replied message (if present)
    chat_type: Optional[str]     # "private", "group", "supergroup", "channel"
    inline_query_id: Optional[str]    # For inline_query events
    callback_query_id: Optional[str]  # For callback_query events
    message_id: Optional[int]    # Message ID (if available)
    username: Optional[str]      # User username (if available)
    first_name: Optional[str]    # User first name (if available)
    chat_title: Optional[str]    # Chat title (for groups/channels)
    last_name: Optional[str]     # User last name (if available)
    language_code: Optional[str] # User language code (if available)
    content_type: Optional[str]  # "text", "photo", "document", etc. (for messages)

Async

Use async def handlers and start the bot with bot.run_async(). For API calls use await bot.async_client.send_message(...) (and the other methods on bot.async_client).

from shingram import Bot

bot = Bot("YOUR_BOT_TOKEN")

@bot.on("command:start")
async def handle_start(event):
    await bot.async_client.send_message(chat_id=event.chat_id, text="Hello!")

@bot.on("message")
async def handle_message(event):
    if event.text:
        await bot.async_client.send_message(chat_id=event.chat_id, text=f"You said: {event.text}")

bot.run_async()

You can pass optional polling options to run() and run_async(): timeout (default 30), limit (default 100), allowed_updates (list of update types, or None for all), and on_error (callback for polling-loop errors, e.g. bot.run(on_error=logger.exception)).

Error Handling

from shingram import Bot, TelegramAPIError

try:
    bot.send_message(chat_id=123, text="Test")
except TelegramAPIError as e:
    print(f"Telegram API error: {e}")
    print(f"Error code: {e.error_code}")
    print(f"Description: {e.description}")

Examples

See the examples/ directory in the repo. You can find plenty of examples there: sync (e.g. echo_bot.py, inline_bot.py, keyboard_bot.py, webhook_flask.py, webhook_fastapi.py) and async (e.g. echo_bot_async.py, inline_bot_async.py, keyboard_bot_async.py). Set your bot token in the file and run it.

License

MIT License - see LICENSE for details.

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

shingram-0.3.0.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shingram-0.3.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file shingram-0.3.0.tar.gz.

File metadata

  • Download URL: shingram-0.3.0.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.15

File hashes

Hashes for shingram-0.3.0.tar.gz
Algorithm Hash digest
SHA256 a5cab873871fb88bf1cda53900a3389db74f4554dfac5dc235e57f7059d2811b
MD5 5c97aab8632a01fd326f9c46831c1955
BLAKE2b-256 2f1c42e9e465990e1e4c234f0976ce2aab3f61f2f98652934b22e821c79971c3

See more details on using hashes here.

File details

Details for the file shingram-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: shingram-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.15

File hashes

Hashes for shingram-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 571326c0c4d7772ac48f54a159c0a67d14de619a20b54e01349b2d5cf0f8d8a0
MD5 0cd3faa727a67c88755e9698179be17e
BLAKE2b-256 f7f11671420598e59b9fbc4f8eec8b40acff2d38e48a81341116b03e644e3235

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page