Per-Handler Guards

Scope middleware to a single handler with @use_middleware instead of running it on every update. v0.5.0

Basic Usage

guards.py
from kurigram_addons import use_middleware
from pyrogram import StopPropagation

async def require_admin(update, client, patch_helper):
    if update.from_user.id not in ADMIN_IDS:
        await update.reply("⛔ Admins only.")
        raise StopPropagation

@router.on_command("ban")
@use_middleware(require_admin)   # only runs for /ban
async def ban_cmd(client, message):
    await message.reply("Banned!")

Stacking guards

Multiple @use_middleware decorators execute outermost-first.

stacked.py
@router.on_command("broadcast")
@use_middleware(require_admin)
@use_middleware(RateLimit(per_user=1, window=60))
async def broadcast_cmd(client, message):
    ...

Around middleware

Wrap a handler with before/after logic using the @middleware decorator. The wrapped function receives a handler callable as its first argument.

timing.py
from kurigram_addons import middleware
import time

@router.on_command("slow")
@middleware
async def slow_cmd(handler, client, message):
    t = time.perf_counter()
    await handler()          # call the actual handler body
    elapsed = (time.perf_counter() - t) * 1000
    await message.reply(f"Took {elapsed:.1f}ms")

Notes

  • Per-handler guards only run for the decorated handler — not globally.
  • Raising StopPropagation from a guard blocks the handler and stops further propagation.
  • Guards execute in the order decorators are applied (outermost first).
  • The global middleware pipeline still runs before per-handler guards.