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
StopPropagationfrom 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.