Repository navigation
v0.5.0
What's Changed
Added
-
Multi-Tenancy Module (
eventsource.multitenancy) - First-class multi-tenant supporttenant_contextContextVar for managing tenant context across async boundariestenant_scopeasync context manager for scoped tenant operationstenant_scope_syncsync context manager for synchronous code paths- Helper functions:
get_current_tenant(),get_required_tenant(),set_current_tenant(),clear_tenant_context() TenantDomainEventbase class with requiredtenant_idfield andwith_tenant_context()class methodTenantAwareRepositorywrapper that enforces tenant isolation on load/save operationsTenantContextNotSetErrorandTenantMismatchErrorexceptions for clear error handling- Tenant-aware projections with automatic filtering via
tenant_filterparameter - Public exports from
eventsource:tenant_context,tenant_scope,tenant_scope_sync,get_current_tenant,get_required_tenant,set_current_tenant,clear_tenant_context,TenantDomainEvent,TenantContextNotSetError,TenantMismatchError
-
Sync Adapter (
eventsource.sync) - Synchronous wrappers for async componentsSyncEventStoreAdapterfor using async event stores in synchronous contexts- Ideal for Celery tasks, Django management commands, RQ workers, and other sync environments
- Configurable timeout for operations (default: 30 seconds)
- Public export from
eventsource:SyncEventStoreAdapter
-
Testing Module (
eventsource.testing) - Comprehensive testing utilitiesEventBuilder- Fluent builder for creating test events with minimal boilerplatewith_aggregate_id(),with_version(),with_tenant_id(),with_timestamp()chainable methodsbuild()for single events,build_sequence()for event chains
InMemoryTestHarness- Pre-configured in-memory infrastructure for fast tests- Includes event store, event bus, checkpoint repository, and DLQ
setup()andteardown()lifecycle methodsclear()to reset state between tests
EventAssertions- Domain-specific test assertions with clear error messagesassert_event_published(),assert_no_events_published(),assert_event_count()assert_event_sequence()for verifying event orderingassert_aggregate_version(),assert_aggregate_state()
- BDD-style helpers for readable tests:
given_events()- Set up initial event historywhen_command()- Execute a command/actionthen_event_published()- Assert expected event was publishedthen_no_events_published()- Assert no events were publishedthen_event_sequence()- Assert specific sequence of eventsthen_event_count()- Assert number of events
- Public exports from
eventsource.testing:EventBuilder,InMemoryTestHarness,EventAssertions,given_events,when_command,then_event_published,then_no_events_published,then_event_sequence,then_event_count
-
Aggregate
create_event()Method - Reduced boilerplate for event creation- Auto-populates
aggregate_id,aggregate_type, andaggregate_version - Auto-populates
tenant_idfrom context when available - Explicit kwargs always override auto-populated values
- Example:
self.create_event(OrderShipped, tracking_number="TRACK-001")instead of manually setting all aggregate fields
- Auto-populates
-
Deferred State Pattern - Aggregates without upfront initial state
requires_creation_eventclass attribute onDeclarativeAggregate- When
True,_get_initial_state()returnsNoneand state is set by first event handler AggregateNotCreatedErrorraised when accessingstatebefore creation event applied- Useful for aggregates where initial state depends entirely on creation event data
-
Automatic Type Inference - Less boilerplate for events and aggregates
DomainEvent.event_typenow auto-infers from class name if not explicitly setDomainEvent.aggregate_typeauto-infers from aggregate'saggregate_typewhen created viacreate_event()- Aggregate state type (
TState) auto-detected from Generic parameter
Changed
- InMemoryEventBus - Now thread-safe with proper locking for concurrent access
- AggregateRoot._get_initial_state() - Return type changed from
TStatetoTState | Noneto support deferred state pattern
Tests
- Added multi-tenancy module tests (
tests/unit/multitenancy/)- Context management tests (
test_context.py) - TenantDomainEvent tests (
test_events.py) - TenantAwareRepository tests (
test_repository.py) - Projection tenant filtering tests (
tests/unit/projections/test_tenant_filter.py)
- Context management tests (
- Added sync adapter tests (
tests/unit/sync/)- Adapter functionality tests (
test_adapter.py) - Concurrency tests (
test_concurrency.py)
- Adapter functionality tests (
- Added testing module tests (
tests/unit/testing/)- EventBuilder tests (
test_builder.py) - InMemoryTestHarness tests (
test_harness.py) - EventAssertions tests (
test_assertions.py) - BDD helpers tests (
test_bdd.py) - Module structure tests (
test_module_structure.py)
- EventBuilder tests (
- Added aggregate improvement tests
create_event()tests (tests/unit/aggregates/test_create_event.py)- Deferred state tests (
tests/unit/aggregates/test_deferred_state.py) - Type inference tests (
tests/unit/aggregates/test_aggregate_type_inference.py)
- Added automatic event type inference tests (
tests/unit/test_event_type_auto.py) - Added InMemoryEventBus threading tests (
tests/unit/bus/test_memory.py)
Installation
pip install eventsource-py==0.5.0