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: oridecon.dev/quadkit
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.46
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.46.tar.gz | 279.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| quadkit_events-0.0.46-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 547.5 kB
Release files / quadkit_events-0.0.46.tar.gz
| Download URL | quadkit_events-0.0.46.tar.gz |
|---|---|
| Size | 279.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
442d52dda8a989b71422642b1f1539729d585d57097b1073c6ee9b419c9f94f8
|
|
BLAKE2b-256 checksum How to use checksums |
ac93d956ae96b3189607124759f0fc8367f449264777481b2ea5b477829d9b91
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / quadkit_events-0.0.46-py3-none-any.whl
| Download URL | quadkit_events-0.0.46-py3-none-any.whl |
|---|---|
| Size | 267.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
84c988158b13b05b3324e7c1688ec21656a4fc598b3d33bd4cfc6788f92af745
|
|
BLAKE2b-256 checksum How to use checksums |
fab29c564c365539083106a5a394127a74e8223cf33199a4a85c254fa75531e6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for quadkit-events 0.0.46
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.