Skip to main content

Spakky Event

Spakky Framework를 위한 이벤트 처리 stereotype입니다.

설치

pip install spakky-event

주요 기능

  • @EventHandler: 이벤트 handler 클래스용 stereotype
  • @on_event: 메서드를 이벤트 handler로 표시하는 decorator
  • 타입 안전성: 이벤트 타입에 대한 타입 힌트 지원
  • 비동기 지원: 이벤트 처리에 async/await 네이티브 지원

빠른 시작

이벤트 정의

이벤트는 spakky-domain의 이벤트 기반 클래스 중 하나를 상속해야 합니다.

  • bounded context 내부 이벤트(in-process domain event)에는 AbstractDomainEvent를 사용합니다.
  • 경계를 넘는 이벤트(message broker integration)에는 AbstractIntegrationEvent를 사용합니다.

메시지 브로커 플러그인(RabbitMQ/Kafka)을 사용할 때는 이벤트를 AbstractIntegrationEvent로 정의하세요.

from spakky.core.common.mutability import immutable
from spakky.domain.models.event import AbstractIntegrationEvent


@immutable
class UserCreatedEvent(AbstractIntegrationEvent):
    user_id: str
    email: str


@immutable
class UserDeletedEvent(AbstractIntegrationEvent):
    user_id: str

EventHandler 생성

@EventHandler stereotype과 @on_event decorator를 함께 사용합니다.

from spakky.event.stereotype.event_handler import EventHandler, on_event


@EventHandler()
class UserEventHandler:
    def __init__(self, notification_service: NotificationService) -> None:
        self.notification_service = notification_service

    @on_event(UserCreatedEvent)
    async def on_user_created(self, event: UserCreatedEvent) -> None:
        await self.notification_service.send_welcome_email(event.email)

    @on_event(UserDeletedEvent)
    async def on_user_deleted(self, event: UserDeletedEvent) -> None:
        await self.notification_service.send_goodbye_email(event.user_id)

메시지 브로커 통합

@EventHandler stereotype은 Spakky의 message broker 플러그인과 함께 동작합니다.

RabbitMQ

pip install spakky-rabbitmq
from spakky.core.application.application import SpakkyApplication
from spakky.core.application.application_context import ApplicationContext

app = (
    SpakkyApplication(ApplicationContext())
    .load_plugins()  # Loads spakky-rabbitmq plugin
    .scan()
    .start()
)

Kafka

pip install spakky-kafka
from spakky.core.application.application import SpakkyApplication
from spakky.core.application.application_context import ApplicationContext

app = (
    SpakkyApplication(ApplicationContext())
    .load_plugins()  # Loads spakky-kafka plugin
    .scan()
    .start()
)

API 레퍼런스

스테레오타입

데코레이터 설명
@EventHandler() 클래스를 event handler로 표시(@Pod 확장)
@on_event(EventType) 메서드를 특정 event type의 handler로 표시

인터페이스

인터페이스 설명
IEventPublisher / IAsyncEventPublisher Event publish 진입점(type-based routing)
IEventBus / IAsyncEventBus Integration event send 진입점(Outbox 경계)
IEventTransport / IAsyncEventTransport 실제 message broker transport. send로 payload를 넘기고, 배치 끝에서 flush로 전송을 확정합니다. 영구적이고 특정 레코드에 귀속되는 거부만 EventDeliveryRejectedError로 통일하며, connection·timeout·queue 등 transport 전체 장애는 client 예외 타입을 보존합니다. 애플리케이션 수명 밖의 발행은 EventTransportNotRunningError로 거부됩니다
IEventConsumer / IAsyncEventConsumer Handler callback 등록
IEventDispatcher / IAsyncEventDispatcher In-process handler dispatch

구현체

클래스 설명
EventMediator / AsyncEventMediator Consumer와 Dispatcher를 결합한 in-process 구현체
EventPublisher / AsyncEventPublisher Type-based router(DomainEvent→Mediator, IntegrationEvent→EventBus)
DirectEventBus / AsyncDirectEventBus 기본 EventBus → EventTransport 위임 구현
AuthContextSnapshotHeaderInjector Event/Outbox outbound header에 signed AuthContextSnapshot metadata를 주입하는 helper
EventHandlerRegistrationPostProcessor @EventHandler 메서드를 자동 등록

전파 metadata

DirectEventBus와 AsyncDirectEventBus는 IEventTransport.send(event_name, payload, headers, partition_key) public signature로 outbound header를 구성하고, 이벤트가 선언한 partition key를 그대로 넘깁니다. 직접 발행은 1건 배치이므로 두 bus는 send 직후 flush를 호출하여 전송을 확정한 뒤 반환합니다.

metadata 조건 설명
traceparent spakky-tracing propagator 활성 기존 W3C tracing header를 보존합니다.
spakky.auth.context_snapshot SPAKKY_AUTH_SNAPSHOT_PROPAGATION_ENABLED=true + request-scope AuthContext + snapshot signer provider raw bearer token 대신 signed AuthContextSnapshot envelope를 전파합니다.

Authorization: Bearer ... 같은 raw bearer credential은 event header로 전파하지 않습니다.

타입

타입 설명
EventRoute event routing metadata용 annotation 클래스
EventT_contra AbstractEvent에 bound된 TypeVar
EventHandlerCallback 동기 event callback용 type alias
AsyncEventHandlerCallback 비동기 event callback용 type alias

에러

클래스 설명
AbstractSpakkyEventError event operation 기반 error
AuthSnapshotPropagationContextUnavailableError snapshot 전파가 활성화되었지만 ApplicationContext를 읽을 수 없을 때 발생
AuthSnapshotPropagationSignerUnavailableError snapshot 전파가 활성화되었지만 signer provider가 없을 때 발생
InvalidMessageError message가 malformed일 때 발생

관련 패키지

패키지 설명
spakky-domain DDD building block 포함 AbstractEvent, AbstractDomainEvent, AbstractIntegrationEvent
spakky-rabbitmq RabbitMQ transport(RabbitMQEventTransport)
spakky-kafka Kafka transport(KafkaEventTransport)

In-process 도메인 이벤트 발행

bounded context 내부 이벤트(DomainEvents)에는 in-process publisher를 사용합니다.

from spakky.core.application.application import SpakkyApplication
from spakky.core.application.application_context import ApplicationContext
from spakky.event import IAsyncEventPublisher

# 애플리케이션 부트스트랩(load_plugins가 event component를 자동 등록)
app = (
    SpakkyApplication(ApplicationContext())
    .load_plugins()
    .scan()
    .start()
)

# 컨테이너에서 publisher 조회
publisher = app.container.get(IAsyncEventPublisher)
await publisher.publish(UserCreatedEvent(user_id="123", email="test@example.com"))

아키텍처(ISP 준수)

in-process event system은 Interface Segregation Principle을 따릅니다.

  • Consumer: event handler 등록(register() 메서드)
  • Dispatcher: event를 handler로 dispatch(dispatch() 메서드)
  • Mediator: 두 인터페이스를 단일 구현체로 결합
  • Publisher: Consumer가 아니라 Dispatcher에만 의존
flowchart TD
    publisher[Publisher]
    dispatcher[Dispatcher]
    mediator["Mediator<br/>Consumer + Dispatcher"]
    handler["EventHandler<br/>@on_event"]

    publisher --> dispatcher
    dispatcher --> mediator
    mediator --> handler

개발 검증

패키지 단위 검증은 해당 패키지 디렉토리에서 실행합니다.

uv run ruff format .
uv run ruff check .
uv run pyrefly check
uv run pytest

pytest는 각 패키지 pyproject.toml의 coverage 설정을 사용합니다.

라이선스

MIT License

Metadata

Release files for spakky-event 8.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spakky-event 8.1.0
File Size Uploaded
spakky_event-8.1.0.tar.gz 11.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for spakky-event 8.1.0
File Interpreter ABI Platform
spakky_event-8.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.8 kB

Release files / spakky_event-8.1.0.tar.gz

Download URL spakky_event-8.1.0.tar.gz
Size 11.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ab5b6cfe876a8a6230f835d76d27e36e2f5d47b950d91d75776aa057e6e9402a
BLAKE2b-256 checksum
How to use checksums
f77ff9531072d727438a6662d4d083c7982c19ae32c51681025117e259311e02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release files / spakky_event-8.1.0-py3-none-any.whl

Download URL spakky_event-8.1.0-py3-none-any.whl
Size 18.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a8f3bc18239e4b595622964f34b3e59562a0363bb0235769ab63dee35c443e20
BLAKE2b-256 checksum
How to use checksums
2e5e683e5ba3daa584d787882d0103fbdb9ccc3123b57960c4bc12ea06b44c52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

8.1.0 This release

2 release files

8.0.0

2 release files

7.2.0

2 release files

7.1.1

2 release files

7.1.0

2 release files

7.0.0

2 release files

6.13.0

2 release files

6.12.0

2 release files

6.11.0

2 release files

6.10.1

2 release files

6.10.0

2 release files

6.9.1

2 release files

6.9.0

2 release files

6.8.0

2 release files

6.7.0

2 release files

6.6.1

2 release files

6.6.0

2 release files

6.5.0

2 release files

6.4.0

2 release files

6.3.1

2 release files

6.3.0

2 release files

6.2.0

2 release files

6.1.3

2 release files

6.1.2

2 release files

6.1.1

2 release files

6.1.0

2 release files

6.0.0

2 release files

5.0.1

2 release files

5.0.0

2 release files

4.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page