spakky-event¶
spakky-event는 이벤트 발행, 소비, dispatch, handler stereotype을 제공하는 core 패키지입니다.
인프로세스 이벤트 시스템 — EventBus, EventTransport, EventMediator
플러그인 진입점¶
initialize(app)
¶
Initialize the spakky-event plugin.
Registers event mediators, publishers, buses, and post-processors.
Source code in core/spakky-event/src/spakky/event/main.py
Publisher 인터페이스¶
Event publishing and transport interfaces.
Provides publisher, bus, and transport abstractions for event routing: - IEventPublisher: Routes events by type (domain vs integration). - IEventBus: Serializes and sends integration events via transport. - IEventTransport: Low-level transport for serialized event payloads.
IEventPublisher
¶
Bases: ABC
Publishes events by routing to dispatcher or bus based on event type.
publish(event)
abstractmethod
¶
IAsyncEventPublisher
¶
Bases: ABC
Async counterpart of IEventPublisher.
IEventBus
¶
IAsyncEventBus
¶
Bases: ABC
Asynchronous event bus for sending integration events.
send(event)
abstractmethod
async
¶
IEventTransport
¶
Bases: ABC
Low-level synchronous transport for pre-serialized event payloads.
The caller owns the publish batch boundary: hand one or more payloads to send() and call flush() once at the end of the batch. Transports may buffer payloads until flush() so that broker round trips are batched.
send(event_name, payload, headers, partition_key=None)
abstractmethod
¶
Hand a serialized event payload to the broker client for delivery.
A permanent rejection attributable to this record must be reported as
EventDeliveryRejectedError. A connection, timeout, queue, or other
transport-wide failure keeps the client exception's original type so a
caller does not spend this record's retry budget.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event_name
|
str
|
Destination topic / routing key. |
required |
payload
|
bytes
|
Pre-serialized event bytes. |
required |
headers
|
dict[str, str]
|
Metadata headers for trace and auth propagation. |
required |
partition_key
|
str | None
|
Key pinning the payload to one broker partition. None spreads payloads round-robin. |
None
|
Raises:
| Type | Description |
|---|---|
EventDeliveryRejectedError
|
When the transport permanently rejects this specific record. |
EventTransportNotRunningError
|
When the transport's broker client is not open, which happens outside the application lifecycle. |
Source code in core/spakky-event/src/spakky/event/event_publisher.py
flush()
abstractmethod
¶
Block until the broker client has finished sending what send() handed over.
A successful return means every record this caller handed over reached the broker. An implementation that learns of a rejection only through a delivery callback collects it and raises here — a caller that batches records has no other moment to learn that the batch did not arrive, and would otherwise record undelivered events as published.
Implementations must preserve the same failure taxonomy as send(): only
a permanent record-specific rejection becomes
EventDeliveryRejectedError; transport-wide failures retain the broker
client's original exception type.
Raises:
| Type | Description |
|---|---|
EventDeliveryRejectedError
|
When one or more records are permanently rejected for a record-specific cause. |
Source code in core/spakky-event/src/spakky/event/event_publisher.py
IAsyncEventTransport
¶
Bases: ABC
Low-level asynchronous transport for pre-serialized event payloads.
The caller owns the publish batch boundary: hand one or more payloads to send() and call flush() once at the end of the batch. Transports may buffer payloads until flush() so that broker round trips are batched. Publishers share one transport, so a batch's send() and flush() belong to the same execution context and flush() reports only that publisher's payloads.
send(event_name, payload, headers, partition_key=None)
abstractmethod
async
¶
Hand a serialized event payload to the broker client for delivery.
A permanent rejection attributable to this record must be reported as
EventDeliveryRejectedError. A connection, timeout, queue, or other
transport-wide failure keeps the client exception's original type so a
caller does not spend this record's retry budget.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event_name
|
str
|
Destination topic / routing key. |
required |
payload
|
bytes
|
Pre-serialized event bytes. |
required |
headers
|
dict[str, str]
|
Metadata headers for trace and auth propagation. |
required |
partition_key
|
str | None
|
Key pinning the payload to one broker partition. None spreads payloads round-robin. |
None
|
Raises:
| Type | Description |
|---|---|
EventDeliveryRejectedError
|
When the transport permanently rejects this specific record. |
EventTransportNotRunningError
|
When the transport's broker client is not open, which happens outside the application lifecycle. |
Source code in core/spakky-event/src/spakky/event/event_publisher.py
flush()
abstractmethod
async
¶
Block until the broker client has finished sending what send() handed over.
A successful return means every record this caller handed over reached the broker. An implementation that learns of a rejection only through a delivery callback collects it and raises here — a caller that batches records has no other moment to learn that the batch did not arrive, and would otherwise record undelivered events as published.
Implementations must preserve the same failure taxonomy as send(): only
a permanent record-specific rejection becomes
EventDeliveryRejectedError; transport-wide failures retain the broker
client's original exception type.
Raises:
| Type | Description |
|---|---|
EventDeliveryRejectedError
|
When one or more records are permanently rejected for a record-specific cause. |
Source code in core/spakky-event/src/spakky/event/event_publisher.py
Consumer 인터페이스¶
Event consumer interfaces for registering event handlers.
EventHandlerCallback = Callable[[EventT_contra], None]
¶
Synchronous event handler callback type.
AsyncEventHandlerCallback = Callable[[EventT_contra], Awaitable[None]]
¶
Asynchronous event handler callback type.
IEventConsumer
¶
Bases: ABC
Synchronous event consumer interface for registering event handlers.
register(event, handler)
abstractmethod
¶
Register a handler callback for the given event type.
Source code in core/spakky-event/src/spakky/event/event_consumer.py
Dispatcher 인터페이스¶
Event dispatcher interfaces for dispatching events to registered handlers.
This module provides unified dispatcher interfaces that handle all event types. Dispatchers are responsible for delivering events to registered handlers, while Consumers are responsible for handler registration. These interfaces are combined in Mediator implementations.
EventBus¶
Default EventBus implementations that delegate to EventTransport.
DirectEventBus(transport, propagator, auth_snapshot_headers=None)
¶
Bases: IEventBus
Synchronous event bus that serializes and delegates to IEventTransport.
Initialize with the given transport and trace propagator.
Source code in core/spakky-event/src/spakky/event/bus/transport_event_bus.py
send(event)
¶
Serialize and send an integration event via transport.
A direct publish is a batch of one, so the transport is flushed before returning and the caller gets the same delivery guarantee as before.
Source code in core/spakky-event/src/spakky/event/bus/transport_event_bus.py
AsyncDirectEventBus(transport, propagator, auth_snapshot_headers=None)
¶
Bases: IAsyncEventBus
Asynchronous event bus that serializes and delegates to IAsyncEventTransport.
Initialize with the given async transport and trace propagator.
Source code in core/spakky-event/src/spakky/event/bus/transport_event_bus.py
send(event)
async
¶
Serialize and send an integration event via async transport.
A direct publish is a batch of one, so the transport is flushed before returning and the caller gets the same delivery guarantee as before.
Source code in core/spakky-event/src/spakky/event/bus/transport_event_bus.py
Auth Propagation¶
Auth snapshot metadata propagation for outbound integration events.
AuthContextSnapshotHeaderInjector(auth_snapshot_signer=None, auth_snapshot_propagation_configs=())
¶
Bases: IApplicationContextAware
Inject signed AuthContextSnapshot metadata into outbound event headers.
Source code in core/spakky-event/src/spakky/event/auth_propagation.py
set_application_context(application_context)
¶
Inject the application context used to read request-scoped auth state.
Source code in core/spakky-event/src/spakky/event/auth_propagation.py
inject(headers)
¶
Add signed snapshot metadata when outbound propagation is enabled.
Source code in core/spakky-event/src/spakky/event/auth_propagation.py
Mediator¶
Event mediator implementations.
This module provides in-process mediator implementations that combine Consumer and Dispatcher interfaces. Mediators manage handler registration and event dispatching within the same bounded context.
EventMediator()
¶
Bases: IEventConsumer, IEventDispatcher
In-process synchronous event mediator combining consumer and dispatcher roles.
Initialize an empty handler registry.
Source code in core/spakky-event/src/spakky/event/mediator/domain_event_mediator.py
register(event, handler)
¶
Register a handler callback for the given event type.
Source code in core/spakky-event/src/spakky/event/mediator/domain_event_mediator.py
dispatch(event)
¶
Dispatch an event to all registered handlers.
Source code in core/spakky-event/src/spakky/event/mediator/domain_event_mediator.py
AsyncEventMediator()
¶
Bases: IAsyncEventConsumer, IAsyncEventDispatcher
In-process asynchronous event mediator combining consumer and dispatcher roles.
Initialize an empty async handler registry.
Source code in core/spakky-event/src/spakky/event/mediator/domain_event_mediator.py
register(event, handler)
¶
Register an async handler callback for the given event type.
Source code in core/spakky-event/src/spakky/event/mediator/domain_event_mediator.py
dispatch(event)
async
¶
Dispatch an event to all registered async handlers.
Source code in core/spakky-event/src/spakky/event/mediator/domain_event_mediator.py
Publisher¶
Event publisher implementations.
This module provides event publishers that route events by type: - AbstractDomainEvent → EventMediator (in-process dispatch) - AbstractIntegrationEvent → IEventBus (external transport)
EventPublisher(dispatcher, bus)
¶
Bases: IEventPublisher
Routes events by type: domain events to dispatcher, integration events to bus.
Initialize with dispatcher and bus dependencies.
Source code in core/spakky-event/src/spakky/event/publisher/domain_event_publisher.py
publish(event)
¶
Route an event to the appropriate handler based on its type.
Source code in core/spakky-event/src/spakky/event/publisher/domain_event_publisher.py
AsyncEventPublisher(dispatcher, bus)
¶
Bases: IAsyncEventPublisher
Async counterpart that routes events by type.
Initialize with async dispatcher and bus dependencies.
Source code in core/spakky-event/src/spakky/event/publisher/domain_event_publisher.py
publish(event)
async
¶
Route an event to the appropriate async handler based on its type.
Source code in core/spakky-event/src/spakky/event/publisher/domain_event_publisher.py
Aspect¶
Transactional event publishing aspect for automatic domain event publishing.
AsyncTransactionalEventPublishingAspect(collector, publisher)
¶
Bases: IAsyncAspect
Source code in core/spakky-event/src/spakky/event/aspects/transactional_event_publishing.py
after_returning_async(result)
async
¶
Publish domain events from collected aggregates after successful commit.
Source code in core/spakky-event/src/spakky/event/aspects/transactional_event_publishing.py
after_async()
async
¶
Clear the aggregate collector after transaction completion.
Source code in core/spakky-event/src/spakky/event/aspects/transactional_event_publishing.py
TransactionalEventPublishingAspect(collector, publisher)
¶
Bases: IAspect
Source code in core/spakky-event/src/spakky/event/aspects/transactional_event_publishing.py
after_returning(result)
¶
Publish domain events from collected aggregates after successful commit.
Source code in core/spakky-event/src/spakky/event/aspects/transactional_event_publishing.py
after()
¶
Clear the aggregate collector after transaction completion.
Source code in core/spakky-event/src/spakky/event/aspects/transactional_event_publishing.py
스테레오타입¶
EventHandler stereotype and event routing decorators.
This module provides @EventHandler stereotype and @on_event decorator for organizing event-driven architectures.
EventHandlerMethod = Callable[[Any, EventT_contra], None | Awaitable[None]]
¶
Type alias for event handler callback functions.
EventRoute(event_type)
dataclass
¶
Bases: FunctionAnnotation
Annotation for marking methods as event handlers.
Associates a method with a specific domain event type.
event_type
instance-attribute
¶
The domain event type this handler processes.
__call__(obj)
¶
Apply event route annotation to method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
EventHandlerMethod[EventT_contra]
|
The method to annotate. |
required |
Returns:
| Type | Description |
|---|---|
EventHandlerMethod[EventT_contra]
|
The annotated method. |
Source code in core/spakky-event/src/spakky/event/stereotype/event_handler.py
EventHandler(*, name='', scope=Scope.SINGLETON)
dataclass
¶
Bases: Pod
Stereotype for event handler classes.
EventHandlers contain methods decorated with @on_event that process domain events asynchronously.
on_event(event_type)
¶
Decorator for marking methods as event handlers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event_type
|
type[EventT_contra]
|
The domain event type to handle. |
required |
Returns:
| Type | Description |
|---|---|
Callable[[EventHandlerMethod[EventT_contra]], EventHandlerMethod[EventT_contra]]
|
Decorator function that applies EventRoute annotation. |
Example
@EventHandler() class UserEventHandler: @on_event(UserCreatedEvent) async def handle_user_created(self, event: UserCreatedEvent) -> None: # Handle event pass
Source code in core/spakky-event/src/spakky/event/stereotype/event_handler.py
후처리기¶
Event handler registration post-processor.
EventHandlerRegistrationPostProcessor
¶
Bases: IPostProcessor, IContainerAware
Scans @EventHandler Pods and registers their @on_event methods with consumers.
set_container(container)
¶
post_process(pod)
¶
Register event handler methods with the appropriate consumer.
Source code in core/spakky-event/src/spakky/event/post_processor.py
에러¶
AbstractSpakkyEventError
¶
InvalidMessageError
¶
AuthSnapshotPropagationSignerUnavailableError
¶
AuthSnapshotPropagationContextUnavailableError
¶
Bases: AbstractSpakkyEventError
Raised when signed snapshot propagation cannot read ApplicationContext.
EventTransportNotRunningError
¶
Bases: AbstractSpakkyEventError
Raised when a transport is used outside the application lifecycle.
Transports whose broker client is opened at application start and closed at application stop raise this instead of publishing into a closed client, so that callers can tell a shutdown window apart from a delivery failure.
EventDeliveryRejectedError(reasons)
¶
Bases: AbstractSpakkyEventError
Raised when a transport attributes a permanent rejection to a record.
A client may report the rejection synchronously from send() or later through a delivery callback consumed by flush(). Both paths use this error so callers can distinguish record-specific failure from a transport-wide outage.
Source code in core/spakky-event/src/spakky/event/error.py
UnknownEventTypeError(event_type)
¶
Bases: AbstractSpakkyEventError
Raised when an event type is neither domain nor integration.