quadkit-events
Event Sourcing and CQRS engine for Quadkit Framework — domain events, aggregates, and projections.
Overview
CQRS, Event Sourcing, and messaging for Quadkit — command bus, event bus, event store, sagas, and projections. Provides a full CQRS stack: a typed command bus, an in-process pub/sub event bus, an append-only event store (PostgreSQL, SQLite, MongoDB, in-memory), saga orchestration, projections, and outbox processing.
Use EventsModule.configure() to register the event system and dispatch commands
or subscribe to events via decorators.
Full documentation: docs.quadkit.dev
Install
uv add quadkit-events
# Optional extras
uv add "quadkit-events[postgres,sqlite,mongo]"
Quick Start
from quadkit import Application
from quadkit.di.module import Module, module
from quadkit.events import EventsModule, EventsConfig
@module(imports=[EventsModule.configure()])
class AppModule(Module):
pass
async def main():
async with Application.boot(modules=[AppModule]) as app:
# your event sourcing code
...
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Configuration
Zero-config usage: Call
EventsModule.configure()with no arguments to use defaults (in-memory event store and bus).
Option 1 — YAML file
# application.yaml
events:
event_store_backend: postgres
postgres:
dsn: "${DATABASE_URL}"
Option 2 — Profiles + Environment Variables (recommended)
export QK_EVENTS__EVENT_STORE_BACKEND=postgres
export QK_EVENTS__POSTGRES__DSN="postgresql://user:pass@host/db"
Option 3 — Python
from quadkit.events import EventsConfig, EventsModule, PostgresEventStoreConfig
from quadkit.events.types import EventStoreBackend
config = EventsConfig(
event_store_backend=EventStoreBackend.POSTGRES,
postgres=PostgresEventStoreConfig(dsn="${DATABASE_URL}"),
)
EventsModule.configure(config)
Config reference
| Field | Default | Env var | Description |
|---|---|---|---|
event_store_backend |
memory |
QK_EVENTS__EVENT_STORE_BACKEND |
Store backend: postgres, sqlite, mongodb, memory |
event_bus.max_concurrent_handlers |
10 |
QK_EVENTS__EVENT_BUS__MAX_CONCURRENT_HANDLERS |
Max concurrent handler tasks |
event_bus.enable_dead_letter |
True |
QK_EVENTS__EVENT_BUS__ENABLE_DEAD_LETTER |
Send failed events to dead-letter queue |
Module Factory Methods
| Method | Description |
|---|---|
EventsModule.configure(...) |
Configure with explicit EventsConfig |
EventsModule.stub() |
In-memory event store for testing |
WebSocket Event Streaming
EventWebSocketEndpoint streams every event published to a
StreamDispatcher to connected WebSocket clients in real time.
Security: the endpoint does not authenticate connections by default. With no
authorizecallback, any client that can reach the endpoint receives a live, unauthenticated stream of all dispatched events — potentially business-sensitive or PII-bearing. Always pass anauthorizecallback in production:
from quadkit.events.streaming import EventWebSocketEndpoint, StreamDispatcher
def authorize(scope: dict) -> bool:
headers = dict(scope.get("headers") or [])
return headers.get(b"authorization") == b"Bearer secret"
dispatcher = StreamDispatcher()
ws_app = EventWebSocketEndpoint(dispatcher, authorize=authorize)
The callback receives the ASGI connection scope (headers, query
string, client) and may be synchronous or asynchronous; returning a
falsy value rejects the connection with a 4401 close before the
handshake is accepted.
Key Features
- CommandBus — Typed async command dispatch with middleware
- EventBus — In-process pub/sub with dead-letter handling
- EventStore — Append-only store (PostgreSQL, SQLite, MongoDB, in-memory)
- Saga — Long-running process orchestration with compensating transactions
- Projection — Read-model rebuilding from event streams
- Outbox — Reliable event delivery via transactional outbox pattern
- Schema migration — Versioned event schema evolution
Testing
async with Application.boot(modules=[EventsModule.stub()]) as app:
# your test code
...
Key Source Files
| File | What it contains |
|---|---|
src/quadkit/events/module.py |
EventsModule definition |
src/quadkit/events/config.py |
EventsConfig and all config sub-models |
src/quadkit/events/di/provider.py |
EventsProvider wiring |
src/quadkit/events/buses/ |
CommandBus, EventBus, QueryBus implementations |
src/quadkit/events/stores/ |
Event store implementations (memory, postgres, etc.) |
Metadata
Release files for quadkit-events 0.0.44
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| quadkit_events-0.0.44.tar.gz | 273.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| quadkit_events-0.0.44-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 539.5 kB
Release files / quadkit_events-0.0.44.tar.gz
| Download URL | quadkit_events-0.0.44.tar.gz |
|---|---|
| Size | 273.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
47b4cc382dcf8968d3d27cc68280445e34d19e41efc0337d8156c47bf651ce2f
|
|
BLAKE2b-256 checksum How to use checksums |
bda5fd45094d037e18cda1567107b249a0b2cc5e0bb1a41d7ecd75155490803f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.14
|
Release files / quadkit_events-0.0.44-py3-none-any.whl
| Download URL | quadkit_events-0.0.44-py3-none-any.whl |
|---|---|
| Size | 265.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cfb1637703dc1a8198fc81953a596cc12ead6257656c2b35bb76ec56a634c8ed
|
|
BLAKE2b-256 checksum How to use checksums |
76d5c346cf02037c62d9701824b9dc59d85c28a1bb17a4c785cbd67d2c1993b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.14
|
Security for quadkit-events 0.0.44
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.