lexigram-events
Event Sourcing and CQRS engine for Lexigram Framework — domain events, aggregates, and projections.
Overview
CQRS, Event Sourcing, and messaging for Lexigram — 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.lexigram.dev
Install
uv add lexigram-events
# Optional extras
uv add "lexigram-events[postgres,sqlite,mongo]"
Quick Start
from lexigram import Application
from lexigram.di.module import Module, module
from lexigram.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 LEX_EVENTS__EVENT_STORE_BACKEND=postgres
export LEX_EVENTS__POSTGRES__DSN="postgresql://user:pass@host/db"
Option 3 — Python
from lexigram.events import EventsConfig, EventsModule, PostgresEventStoreConfig
from lexigram.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 |
LEX_EVENTS__EVENT_STORE_BACKEND |
Store backend: postgres, sqlite, mongodb, memory |
event_bus.max_concurrent_handlers |
10 |
LEX_EVENTS__EVENT_BUS__MAX_CONCURRENT_HANDLERS |
Max concurrent handler tasks |
event_bus.enable_dead_letter |
True |
LEX_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 lexigram.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/lexigram/events/module.py |
EventsModule definition |
src/lexigram/events/config.py |
EventsConfig and all config sub-models |
src/lexigram/events/di/provider.py |
EventsProvider wiring |
src/lexigram/events/buses/ |
CommandBus, EventBus, QueryBus implementations |
src/lexigram/events/stores/ |
Event store implementations (memory, postgres, etc.) |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lexigram_events-0.1.4.tar.gz.
File metadata
- Download URL: lexigram_events-0.1.4.tar.gz
- Upload date:
- Size: 268.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.8.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ceefb8c9409f30ea2cde658e05a52e8920a8e095c17b7aaa627736b448889a2
|
|
| MD5 |
512f28ab852f8c99a6649446e0694641
|
|
| BLAKE2b-256 |
bd4ef1e43d7a44d8cf5968e73e8b65c99387dfe9241658490b32cd40305fc4e6
|
File details
Details for the file lexigram_events-0.1.4-py3-none-any.whl.
File metadata
- Download URL: lexigram_events-0.1.4-py3-none-any.whl
- Upload date:
- Size: 253.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.8.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5fa23087569e79ffca0e8c10ca9f5377c633f70cbe0b3d33978740f5b60bbdf0
|
|
| MD5 |
ff5e786300b9cea371ee61a2b283e68c
|
|
| BLAKE2b-256 |
5502e21189a40df681d0f59f7fbdc4638db0108cd14e8bbd5e230fe0c606a857
|