Skip to main content

Modern Telegram Bot Framework for Python - Inspired by GrammyJS

Project description

๐Ÿ PyGrammY 2.0

PyGrammY 2.0 โ€” Python uchun to'liq asinxron, Grammy.js'dan ilhomlangan, zamonaviy Telegram Bot Framework.
Barcha Telegram media turlari, inline query, poll, va boshqa imkoniyatlarni qo'llab-quvvatlaydi.

Version Python License


๐Ÿš€ Xususiyatlar

โœจ Core Features

  • โšก To'liq asinxron (async/await)
  • ๐ŸŒ httpx asosida Telegram Bot API
  • ๐Ÿง  Context (ctx) โ€” barcha ma'lumotlar bitta joyda
  • ๐Ÿ”Œ Middleware chain (GrammyJS uslubida)
  • ๐Ÿ’พ Session (memory & file storage)
  • ๐Ÿงฉ Composer โ€” modular bot arxitekturasi
  • ๐ŸŽฏ Kuchli filters (regex, file extension, user/chat ID)
  • ๐Ÿช Polling va Webhook qo'llab-quvvatlanadi
  • ๐Ÿ›ก๏ธ Global error handling

๐Ÿ“ฆ Media Support

  • ๐Ÿ“ธ Photo (rasm)
  • ๐ŸŽฅ Video
  • ๐ŸŽต Audio
  • ๐ŸŽค Voice (ovozli xabar)
  • ๐Ÿ“น Video Note (dumaloq video)
  • ๐ŸŽž๏ธ Animation (GIF)
  • ๐Ÿท๏ธ Sticker
  • ๐Ÿ“„ Document (har qanday fayl)
  • ๐Ÿ“ Location (joylashuv)
  • ๐Ÿข Venue (joy)
  • ๐Ÿ“ž Contact (kontakt)
  • ๐Ÿ“Š Poll (so'rov)
  • ๐ŸŽฒ Dice (zar, nishon, va boshqalar)
  • ๐Ÿ“ฆ Media Groups (bir nechta media birga)

โŒจ๏ธ Keyboards

  • ๐Ÿ–ฑ๏ธ InlineKeyboard โ€” inline tugmalar
  • โŒจ๏ธ Keyboard โ€” reply klaviatura
  • ๐Ÿ—‘๏ธ RemoveKeyboard โ€” klaviaturani olib tashlash
  • ๐Ÿ’ฌ ForceReply โ€” javob berishga majburlash

๐Ÿ” Advanced Features

  • ๐Ÿ”Ž Inline Query qo'llab-quvvatlanadi
  • ๐Ÿ“จ Message forwarding & copying
  • ๐Ÿ“Œ Pin/Unpin messages
  • โœ๏ธ Edit messages (matn, media, keyboard)
  • ๐Ÿ—‘๏ธ Delete messages
  • ๐Ÿ“ฅ File download
  • ๐Ÿ‘ฅ Chat management (ban, restrict, promote)
  • ๐Ÿ’ฌ Chat actions (typing, upload_photo, va boshqalar)

๐Ÿ“ฆ O'rnatish

PyPI orqali (kelajakda)

pip install pygrammy

Lokal o'rnatish

# Dependencies o'rnatish
pip install httpx aiohttp

# Loyihani clone qilish
git clone https://github.com/yourusername/pygrammy
cd pygrammy

# O'rnatish
pip install -e .

๐Ÿง‘โ€๐Ÿ’ป Minimal misol

import asyncio
from pygrammy import Bot

bot = Bot("YOUR_BOT_TOKEN")

@bot.command("start")
async def start(ctx):
    await ctx.reply("๐Ÿ‘‹ Salom! PyGrammY 2.0 ishlayapti!")

async def main():
    async with bot:
        await bot.start()

asyncio.run(main())

๐Ÿ“š O'rganish

Media yuborish

from pygrammy import Bot, InputFile

bot = Bot("TOKEN")

@bot.command("photo")
async def send_photo(ctx):
    # URL orqali
    await ctx.replyWithPhoto("https://example.com/photo.jpg", 
                             caption="Rasm!")
    
    # Lokal fayl
    await ctx.sendPhoto(InputFile("photo.jpg"), caption="Lokal rasm")
    
    # File ID
    await ctx.sendPhoto("AgACAgIAAxkBAAI...", caption="File ID")

@bot.command("video")
async def send_video(ctx):
    await ctx.replyWithVideo(
        InputFile("video.mp4"),
        caption="๐ŸŽฅ Video",
        supports_streaming=True
    )

@bot.command("audio")
async def send_audio(ctx):
    await ctx.sendAudio(
        InputFile("song.mp3"),
        title="Qo'shiq nomi",
        performer="Ijrochi"
    )

Media Group

from pygrammy import InputMediaPhoto, InputMediaVideo, InputFile

@bot.command("album")
async def send_album(ctx):
    media = [
        InputMediaPhoto("https://example.com/1.jpg", caption="Birinchi"),
        InputMediaPhoto("https://example.com/2.jpg", caption="Ikkinchi"),
        InputMediaVideo(InputFile("video.mp4"), caption="Video")
    ]
    await ctx.sendMediaGroup(media)

Inline Keyboard

from pygrammy import InlineKeyboard

@bot.command("menu")
async def menu(ctx):
    kb = InlineKeyboard()
    kb.text("๐Ÿ‘ Like", "like").text("๐Ÿ‘Ž Dislike", "dislike")
    kb.row()
    kb.url("๐ŸŒ Website", "https://example.com")
    kb.switch_inline_query("๐Ÿ” Search", "query")
    
    await ctx.reply("Tanlang:", reply_markup=kb)

@bot.callback_query("like")
async def like_handler(ctx):
    await ctx.answerCallbackQuery("Rahmat! ๐Ÿ‘")
    await ctx.editMessageText("Sizga yoqdi! โค๏ธ")

Reply Keyboard

from pygrammy import Keyboard

@bot.command("keyboard")
async def keyboard(ctx):
    kb = Keyboard()
    kb.text("๐Ÿ  Bosh sahifa").text("๐Ÿ‘ค Profil")
    kb.row()
    kb.request_contact("๐Ÿ“ž Kontakt")
    kb.request_location("๐Ÿ“ Joylashuv")
    kb.resized().one_time()
    
    await ctx.reply("Tanlang:", reply_markup=kb)

ForceReply

from pygrammy import ForceReply

@bot.command("ask")
async def ask(ctx):
    await ctx.reply(
        "Ismingiz nima?",
        reply_markup=ForceReply(
            input_field_placeholder="Ismingizni kiriting..."
        )
    )

Session

from pygrammy import session

bot.use(session(initial=lambda: {"count": 0}))

@bot.on("message:text")
async def counter(ctx):
    ctx.session["count"] += 1
    await ctx.reply(f"Xabarlar soni: {ctx.session['count']}")

Filters

from pygrammy import Filters

# Media filtrlari
@bot.filter(Filters.photo)
async def photo_handler(ctx):
    await ctx.reply("๐Ÿ“ธ Rasm qabul qilindi!")

@bot.filter(Filters.video)
async def video_handler(ctx):
    await ctx.reply("๐ŸŽฅ Video qabul qilindi!")

# Regex filter
@bot.filter(Filters.regex(r"(?i)salom|hello"))
async def greeting(ctx):
    await ctx.reply("๐Ÿ‘‹ Salom!")

# User ID filter
@bot.filter(Filters.user_id(123456, 789012))
async def admin_only(ctx):
    await ctx.reply("๐Ÿ‘‘ Admin panel")

# File extension filter
@bot.filter(Filters.file_extension("pdf", "docx"))
async def document_handler(ctx):
    await ctx.reply("๐Ÿ“„ PDF yoki DOCX fayl!")

# Kombinatsiya
admin_filter = Filters.user_id(123456) & Filters.private_chat
@bot.filter(admin_filter)
async def admin_private(ctx):
    await ctx.reply("Admin + Private chat")

Message Operations

# Forward
@bot.command("forward")
async def forward(ctx):
    if ctx.message.reply_to_message:
        await ctx.forwardMessage(
            from_chat_id=ctx.chat_id,
            message_id=ctx.message.reply_to_message.message_id
        )

# Copy (forward signature'siz)
@bot.command("copy")
async def copy(ctx):
    if ctx.message.reply_to_message:
        await ctx.copyMessage(
            from_chat_id=ctx.chat_id,
            message_id=ctx.message.reply_to_message.message_id
        )

# Pin
@bot.command("pin")
async def pin(ctx):
    if ctx.message.reply_to_message:
        await ctx.pinChatMessage(
            message_id=ctx.message.reply_to_message.message_id
        )

# Delete
@bot.command("delete")
async def delete(ctx):
    await ctx.deleteMessage()

Chat Actions

@bot.command("typing")
async def typing_demo(ctx):
    await ctx.sendChatAction("typing")
    await asyncio.sleep(3)
    await ctx.reply("Yozdim!")

# Actions: typing, upload_photo, record_video, upload_video,
#          record_voice, upload_voice, upload_document,
#          choose_sticker, find_location, record_video_note

Poll

@bot.command("poll")
async def create_poll(ctx):
    await ctx.sendPoll(
        question="PyGrammY 2.0 qanday?",
        options=["๐Ÿ˜ Zo'r", "๐Ÿ‘ Yaxshi", "๐Ÿ˜ O'rtacha"],
        is_anonymous=False,
        allows_multiple_answers=False
    )

# Poll to'xtatish
@bot.command("stop_poll")
async def stop_poll(ctx):
    if ctx.message.reply_to_message:
        await ctx.stopPoll(
            message_id=ctx.message.reply_to_message.message_id
        )

Inline Query

@bot.on("inline_query")
async def inline_handler(ctx):
    query = ctx.inline_query.query
    
    results = [
        {
            "type": "article",
            "id": "1",
            "title": "Salom",
            "description": "Salomlashish",
            "input_message_content": {
                "message_text": f"๐Ÿ‘‹ Salom! Query: {query}"
            }
        },
        {
            "type": "photo",
            "id": "2",
            "photo_url": "https://example.com/photo.jpg",
            "thumb_url": "https://example.com/thumb.jpg",
            "caption": "Rasm natijasi"
        }
    ]
    
    await ctx.answerInlineQuery(results, cache_time=300)

File Download

@bot.on("message:document")
async def download_file(ctx):
    doc = ctx.message.document
    
    # File info olish
    file_info = await ctx.getFile(doc.file_id)
    
    # Download qilish
    file_bytes = await ctx.downloadFile(doc.file_id)
    
    # Yoki faylga saqlash
    await ctx.downloadFile(doc.file_id, f"downloads/{doc.file_name}")
    
    await ctx.reply(f"โœ… Fayl yuklandi: {doc.file_name}")

Middleware

@bot.use
async def logger(ctx, next):
    print(f"Update: {ctx.update.update_id}")
    print(f"User: {ctx.from_user.first_name if ctx.from_user else 'N/A'}")
    await next()

@bot.use
async def auth_middleware(ctx, next):
    allowed_users = [123456, 789012]
    if ctx.from_user and ctx.from_user.id in allowed_users:
        await next()
    else:
        await ctx.reply("โ›”๏ธ Kirish taqiqlangan!")

Error Handling

@bot.catch
async def error_handler(error, ctx):
    print(f"โŒ Error: {error}")
    if ctx and ctx.chat_id:
        await ctx.reply("Xatolik yuz berdi. Qayta urinib ko'ring.")

Webhook

await bot.start(webhook={
    "domain": "https://example.com",
    "path": "/webhook",
    "port": 8443
})

๐Ÿงฉ Composer (Modular Architecture)

# handlers/start.py
from pygrammy import Composer

start_router = Composer()

@start_router.command("start")
async def start(ctx):
    await ctx.reply("Salom!")

# main.py
from handlers.start import start_router

bot.use(start_router)

๐Ÿ“– To'liq misol

example_bot.py faylida barcha xususiyatlarni o'z ichiga olgan to'liq misol bor:

# Bot tokenini kiriting
python example_bot.py

Misol botda:

  • โœ… Barcha media turlari
  • โœ… Inline va Reply keyboards
  • โœ… Session
  • โœ… Filters
  • โœ… Inline query
  • โœ… Polls
  • โœ… Message forwarding
  • โœ… File download
  • โœ… Error handling

๐Ÿ†š GrammyJS bilan taqqoslash

Xususiyat GrammyJS PyGrammY 2.0
Til JavaScript/TS Python
Async Promise async/await
HTTP fetch httpx
Typing TypeScript Type hints
Middleware โœ… โœ…
Session โœ… โœ…
Filters โœ… โœ…
Inline Query โœ… โœ…
Media Groups โœ… โœ…
File Download โœ… โœ…

๐Ÿ”„ 1.0 โ†’ 2.0 O'zgarishlar

Yangi xususiyatlar

  • โœ… Barcha media turlari (Audio, Video, Animation, Voice, VideoNote, Sticker)
  • โœ… InputFile va InputMedia class'lari
  • โœ… ForceReply keyboard
  • โœ… Inline query qo'llab-quvvatlanadi
  • โœ… Poll yaratish va boshqarish
  • โœ… Message forward/copy/pin operatsiyalari
  • โœ… File download funksiyasi
  • โœ… Chat management metodlari
  • โœ… Chat actions (typing, upload_photo, va h.k.)
  • โœ… Kengaytirilgan filtrlar (regex, file extension, user/chat ID)
  • โœ… Grammy.js uslubida metodlar (replyWithPhoto, sendChatAction)

Backward Compatibility

Version 1.0 API'lari hamma ham ishlaydi! Yangi features qo'shimcha imkoniyatlar.


๐Ÿ“ Litsenziya

MIT License - batafsil ma'lumot uchun LICENSE faylini ko'ring.


๐Ÿค Hissa qo'shish

Pull request'lar va issue'lar qabul qilinadi!

  1. Fork qiling
  2. Feature branch yarating (git checkout -b feature/amazing)
  3. Commit qiling (git commit -m 'Add amazing feature')
  4. Push qiling (git push origin feature/amazing)
  5. Pull Request oching

๐Ÿ“ž Aloqa


โญ๏ธ Rahmat!

Agar PyGrammY yoqsa, โญ๏ธ bosishni unutmang!

Happy Coding! ๐Ÿš€

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

pygrammy-2.0.0.tar.gz (24.1 kB view details)

Uploaded Source

Built Distribution

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

pygrammy-2.0.0-py3-none-any.whl (22.3 kB view details)

Uploaded Python 3

File details

Details for the file pygrammy-2.0.0.tar.gz.

File metadata

  • Download URL: pygrammy-2.0.0.tar.gz
  • Upload date:
  • Size: 24.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for pygrammy-2.0.0.tar.gz
Algorithm Hash digest
SHA256 8c534ea0816490d4441bc80e8e2b928464caf1874953cbdec45a06c5405d0915
MD5 0880a05e11c3a852aa2dab20c8c3e94e
BLAKE2b-256 8bc158be3256d4ccae7686f8d3d83aa584b77ff447577c3b639eea71591dd635

See more details on using hashes here.

File details

Details for the file pygrammy-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: pygrammy-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 22.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for pygrammy-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 134df8297e5d5046d9aa592a34d5a1953a4956503b1116d537e7099f57b9e099
MD5 1f9e87a4243e70b68daeb9f7a3572d1c
BLAKE2b-256 db603918ce9cb2be39aa1bf9dcc5afd2f62e59b9ae6fe635843eae39dd326bb9

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