Skip to main content

PyMediate logo

Typed in-process request dispatch for Python 3.12+

PyPI version Python versions MIT License Documentation
Tests Coverage Checked with mypy (strict) OpenSSF Scorecard SLSA Build Level 2


PyMediate routes typed requests to handlers. A request declares its response type, so Mediator.send() preserves that type for static type checkers and editors.

Installation

pip install pymediate

The core package has no required dependencies. Install the optional Dependency Injector integration with pip install 'pymediate[di]'.

First request

import asyncio
from dataclasses import dataclass

from pymediate import Mediator, Request, RequestHandler, Services


@dataclass(frozen=True)
class OrderReceipt:
    order_id: int
    summary: str


@dataclass(frozen=True)
class PlaceOrder(Request[OrderReceipt]):
    customer_id: int
    item: str
    quantity: int


class PlaceOrderHandler(RequestHandler[PlaceOrder]):
    async def __call__(self, request: PlaceOrder) -> OrderReceipt:
        return OrderReceipt(
            order_id=42,
            summary=f"{request.quantity} × {request.item}",
        )


async def main() -> None:
    mediator = Mediator(Services().add(PlaceOrderHandler()).provider())
    receipt = await mediator.send(
        PlaceOrder(customer_id=7, item="tea", quantity=2),
    )
    print(receipt.order_id, receipt.summary)


asyncio.run(main())

The program prints:

42 2 × tea

Read the declarations as follows:

  • OrderReceipt is the response.
  • PlaceOrder(Request[OrderReceipt]) is a request for an OrderReceipt.
  • PlaceOrderHandler(RequestHandler[PlaceOrder]) handles PlaceOrder requests.

The introduction contains an interactive guide to these relationships. The quick start explains the complete dispatch flow.

API at a glance

Need API Result
Send a request to one handler Mediator.send() One response, inferred from Request[T]
Yield results over time Mediator.stream() Typed chunks from StreamRequest[T]
Notify zero or more subscribers Mediator.publish() No response
Wrap request handling PipelineBehavior Shared processing around send()
Supply handlers and behaviors Services or another ServiceProvider Resolved instances

The top-level package is asynchronous. pymediate.sync provides corresponding blocking mediator and handler classes. Shared message types, services, and errors are the same objects in both namespaces.

Type checking and validation

Request[T] records the return type used by send() at static call sites. Separately, PyMediate checks a request handler's parameter annotation, return annotation, and asynchronous or synchronous form when Python defines the handler class.

Configuration can still fail during dispatch. For example, sending a request without a registered handler instance raises an error at that point. The type-safety guide describes which checks happen statically, at class definition, and during dispatch.

Scope and trade-offs

PyMediate provides in-process dispatch. It does not provide a task queue, choose persistence, or require CQRS or hexagonal architecture. Direct calls are often clearer when callers can depend on their collaborators without repeated wiring, and a small hand-written dispatcher can be enough.

The article Using a mediator to reduce change coupling develops the case for a mediator and covers the added indirection, registration, and runtime cost. The comparison documents the current feature set, dated dispatch benchmarks, and a runnable benchmark script.

Documentation

Development

git clone https://github.com/sina-al/pymediate.git
cd pymediate
uv sync --all-extras --group test

uv run poe test
uv run poe check:all

Run uv run poe to list the repository tasks. See CONTRIBUTING.md for the contribution process.

Versioning

PyMediate follows ZeroVer: the major version remains 0. A minor release (0.X.0) can contain a breaking API change or a backward-compatible feature. A patch release (0.X.Y) contains changes that do not alter the public API.

License

PyMediate is available under the MIT License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymediate-0.8.0.tar.gz (1.8 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pymediate-0.8.0-py3-none-any.whl (51.3 kB view details)

Uploaded Python 3

File details

Details for the file pymediate-0.8.0.tar.gz.

File metadata

  • Download URL: pymediate-0.8.0.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for pymediate-0.8.0.tar.gz
Algorithm Hash digest
SHA256 1136c410fdef27cc51091793eddc256d0f22ad479d441a343cf464dee007c36f
MD5 6bb1efa1eee8f77ce6628c0a5009b1ea
BLAKE2b-256 b22defd19dbdd27870e3e8d2142b11a9fbd3ff38ce97aa27f8e6bf6017fc0f3e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymediate-0.8.0.tar.gz:

Publisher: release.yml on sina-al/pymediate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymediate-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: pymediate-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 51.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for pymediate-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e3f6342a1855abe5c6cef5d9724a5b79fee31c6e71a3a36ccfda4ead19de8f54
MD5 4f41aa5005c0e8c6ff93ceecfbbf0c7c
BLAKE2b-256 978ace7f075835d2c6cb57a5e790dc75f830b51df9012ffa187774c06c6407d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymediate-0.8.0-py3-none-any.whl:

Publisher: release.yml on sina-al/pymediate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.10.0

2 files

0.9.0

2 files

This release

0.8.0 This release

2 files

0.7.1

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page