Skip to main content

xtr-event-dispatcher-contracts

The event dispatching contract, and nothing else — so a library that emits events installs nothing else.

python 3.11+ asyncio core dependencies: 0 typed license MIT

Why?

A library that announces what happened — an order placed, a message consumed — should not decide who hears it. It takes an event dispatcher, hands it an event object, and leaves the listeners to the application that wires it. That needs the contract, not a dispatcher:

  • 📣 EventDispatcherInterface — await dispatcher.dispatch(event), and the event comes back.
  • 🛑 Event / StoppableEventInterface — an event any listener can stop.
  • 🔎 ListenerIntrospectionInterface — which listeners an event has, and in which order.
  • 🧷 Listener and event_name_of() — what a listener is called with, and the name an event is known by.
  • 🪶 No dependencies.
from dataclasses import dataclass

from xtr_event_dispatcher_contracts import Event, EventDispatcherInterface


@dataclass(frozen=True)
class MessageConsumed(Event):
    message_id: str


class Worker:
    def __init__(self, events: EventDispatcherInterface) -> None:
        self._events = events

    async def handled(self, message_id: str) -> None:
        await self._events.dispatch(MessageConsumed(message_id))

Install

uv add xtr-event-dispatcher-contracts

Requires Python 3.11+.

Who installs what

Depends on
A library that emits events xtr-event-dispatcher-contracts at runtime.
An application xtr-event-dispatcher, which implements this contract and wires listeners from a container.

xtr-event-dispatcher re-exports Event, StoppableEventInterface, ListenerIntrospectionInterface, Listener and event_name_of rather than redefining them, so a library written against this package and an application using that one share the same objects. Its own EventDispatcherInterface extends the one here with registering listeners.

The contract

class EventDispatcherInterface(Protocol):
    async def dispatch(self, event: T, event_name: str | type | None = None) -> T: ...
  • Names. Events are keyed by name: a string, or a class standing for "<module>.<qualname>" (event_name_of). Without a name, an event is dispatched under its class's.
  • Order. Listeners run highest priority first, one after the other, each awaited before the next. An exception a listener raises reaches the caller unchanged.
  • Stopping. An event that is a StoppableEventInterface stops reaching listeners once one stops it. Event is the base class that does this, frozen dataclasses included: event.stop_propagation().
  • Listeners (Listener) are called with the event, its name and the dispatcher — as many of the three as they take, by position; an awaitable result is awaited.

ListenerIntrospectionInterface reads listeners without registering any: get_listeners(name) in running order (or every event's, given no name), get_listener_priority(name, listener), has_listeners(name=None).

Development

Developed in the python-xtr monorepo, under packages/xtr-event-dispatcher-contracts; run the commands below from there. The python-xtr-event-dispatcher-contracts repository is a read-only copy, so send issues and pull requests to the monorepo.

uv sync
uv run ruff check && uv run ruff format --check && uv run basedpyright && uv run ty check && uv run pytest

License

MIT — see LICENSE.

Release files for xtr-event-dispatcher-contracts 1.2.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 xtr-event-dispatcher-contracts 1.2.0
File Size Uploaded
xtr_event_dispatcher_contracts-1.2.0.tar.gz 7.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for xtr-event-dispatcher-contracts 1.2.0
File Interpreter ABI Platform
xtr_event_dispatcher_contracts-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 17.4 kB

Release files / xtr_event_dispatcher_contracts-1.2.0.tar.gz

Download URL xtr_event_dispatcher_contracts-1.2.0.tar.gz
Size 7.3 kB
Tags Source
SHA-256 checksum
How to use checksums
8c9a6befb505a02fb295fb40343016655efb70cef04800212ea482ce3be026f4
BLAKE2b-256 checksum
How to use checksums
83a89a444302a677b8b987657bf6bba5cafa881bcff6018c628cd1b9cdb60034
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 Sep 26, 2026.

Transparency log

Release files / xtr_event_dispatcher_contracts-1.2.0-py3-none-any.whl

Download URL xtr_event_dispatcher_contracts-1.2.0-py3-none-any.whl
Size 10.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5254ec1625cb09ae4fd504594eb277703e5ffea12112774537ae3dbfbf9be702
BLAKE2b-256 checksum
How to use checksums
371b6a1cd1ae502c46dd20a8853aebbf3db3f6f9932144a9fff26c62fae6a727
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 Sep 26, 2026.

Transparency log

Release history Release notifications | RSS feed

1.4.0

2 release files

1.3.0

2 release files

This release

1.2.0 This release

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