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.3.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.3.0
File Size Uploaded
xtr_event_dispatcher_contracts-1.3.0.tar.gz 7.3 kB Details

Built distribution (wheel)

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

Total release size: 17.4 kB

Release files / xtr_event_dispatcher_contracts-1.3.0.tar.gz

Download URL xtr_event_dispatcher_contracts-1.3.0.tar.gz
Size 7.3 kB
Tags Source
SHA-256 checksum
How to use checksums
888a58ba0134bc71f8c2205dcaa8ad89c834aaab3e4cb974bc30b1fd960c05de
BLAKE2b-256 checksum
How to use checksums
b42e14c306e617cc44a8e566e338a7636cfbf249cbf92658305697c069a3372d
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 27, 2026.

Transparency log

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

Download URL xtr_event_dispatcher_contracts-1.3.0-py3-none-any.whl
Size 10.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f8daf971e4fc5542a3bb2dc1f4f249a352dfa4fd403dc7cb6b4219e91247f7bd
BLAKE2b-256 checksum
How to use checksums
ec1c42ae4bd48ebbba3d79cdc9928c88d65c8c57ab6c6257dfd21cf036d55a95
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 27, 2026.

Transparency log

Release history Release notifications | RSS feed

1.4.0

2 release files

This release

1.3.0 This release

2 release files

1.2.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