Quick-reference recipe card - copy-paste ready.
An order service publishes events; audit and email handlers subscribe independently.
from collections import defaultdict
from dataclasses import dataclass, field
from typing import Callable
Handler = Callable[[ str , dict ], None ]
class EventBus :
def __init__ (self) -> None :
self ._handlers: dict[ str , list[Handler]] = defaultdict( list )
def on (self, event: str , handler: Handler) -> None :
self ._handlers[event].append(handler)
def emit (self, event: str , ** payload) -> None :
for handler in list ( self ._handlers[event]):
handler(event, payload)
@dataclass
class OrderService :
bus: EventBus
orders: list[ dict ] = field( default_factory = list )
def place (self, sku: str , qty: int ) -> dict :
order = { "sku" : sku, "qty" : qty}
self .orders.append(order)
self .bus.emit( "order.placed" , order = order)
return order
def audit_log (_event: str , payload: dict ) -> None :
print ( "AUDIT" , payload)
def send_email (_event: str , payload: dict ) -> None :
print ( "EMAIL confirmation for" , payload[ "order" ][ "sku" ])
bus = EventBus()
bus.on( "order.placed" , audit_log)
bus.on( "order.placed" , send_email)
svc = OrderService(bus)
svc.place( "BOOK-1" , 2 )
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+ , Django 5.2 , Flask 3.1 , Pydantic 2 , PyTorch 2.6+ , pandas 2.2+ , Polars 1.x , ruff 0.9+ , and uv 0.6+ .