Skip to content

🏗️ Architecture Overview

Dispytch is a lightweight, async-first event-handling framework built with composability and extensibility in mind. Here’s a breakdown of its core architecture.


🧩 Core Components

🔖 EventBase

Base class for all events. Each event is a typed Pydantic model enriched with metadata like __topic__ and __event_type__ to control where and how it gets published and consumed.

1
2
3
4
5
6
class UserRegistered(EventBase):
    __topic__ = "user_events"
    __event_type__ = "user_registered"

    user_id: str
    email: str

📤 EventEmitter

Handles outbound events. Wraps a backend-specific producer (Kafka, RabbitMQ, etc.), handles serialization and topic resolution:

1
2
3
4
5
6
producer = ...  # your backend producer setup
emitter = EventEmitter(producer)


async def emit_user_registered():
    await emitter.emit(UserRegistered(user_id="123", email="user@example.com"))

🧠 HandlerGroup

A registry for event handlers. Lets you organize handlers by topic and event type.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class UserRegisteredBody(BaseModel):
    user_id: str
    email: str


user_events = HandlerGroup(default_topic="user_events")


@user_events.handler(event="user_registered")
async def handle_user_registered(event: Event[UserRegisteredBody]):
    print(f"User {event.body.user_id} registered with email {event.body.email}")

📥 EventListener

Handles inbound events. Consumes events from a backend and dispatches them to relevant handlers—fully async.

1
2
3
4
5
6
consumer = ...  # your backend consumer setup
listener = EventListener(consumer)
listener.add_handler_group(user_events)

if __name__ == "__main__":
    asyncio.run(listener.listen())