Skip to main content

Lightweight Mediator pattern (sync/async) for Python

Project description

mediapyr (Python)

Mediator pattern implementation for Python, inspired by MediatR in C#. Provides async-first request/response and pub/sub messaging with optional Dependency Injection (DI).


Installation

pip install mediapyr

Quick Start

Define a Request and Handler

from mediapyr import mediator, Request, IRequestHandler

class Ping(Request):
    def __init__(self, msg: str):
        self.msg = msg

@mediator.request_handler(Ping)
class PingHandler(IRequestHandler):
    async def handle(self, request: Ping) -> str:
        return f"Pong: {request.msg}"

Define an Event and Handlers

from mediapyr import Event, IEventHandler

class UserCreated(Event):
    def __init__(self, username: str):
        self.username = username

@mediator.event_handler(UserCreated)
class SendWelcomeEmail(IEventHandler):
    async def handle(self, event: UserCreated):
        print(f"📧 Send welcome email to {event.username}")

@mediator.event_handler(UserCreated)
class AddToCRM(IEventHandler):
    async def handle(self, event: UserCreated):
        print(f"👤 Add {event.username} to CRM")

Run Example

import asyncio
from mediapyr import mediator

async def main():
    res = await mediator.send(Ping("Hello"))
    print("Send result:", res)

    await mediator.publish(UserCreated("Alice"))

if __name__ == "__main__":
    asyncio.run(main())

Dependency Injection with dependency-injector

mediapyr supports plugging in your own DI provider. Example using dependency-injector:

from dependency_injector import containers, providers
from mediapyr import mediator, IRequestHandler, IEventHandler

# Example services
class EmailService:
    def send(self, user: str):
        print(f"[EmailService] Sent email to {user}")

class UserRepository:
    def add(self, user: str):
        print(f"[UserRepository] Added user {user}")

# Handlers
class SendWelcomeEmail(IEventHandler):
    def __init__(self, email_service: EmailService):
        self._email = email_service
    async def handle(self, event: UserCreated):
        self._email.send(event.username)

class AddToCRM(IEventHandler):
    def __init__(self, repo: UserRepository):
        self._repo = repo
    async def handle(self, event: UserCreated):
        self._repo.add(event.username)

class PingHandler(IRequestHandler):
    async def handle(self, request: Ping) -> str:
        return f"Pong from DI: {request.msg}"

# Setup DI container
class Container(containers.DeclarativeContainer):
    wiring_config = containers.WiringConfiguration()

    # Services (singleton)
    email_service = providers.Singleton(EmailService)
    user_repo = providers.Singleton(UserRepository)

    # Handlers (factory/transient)
    SendWelcomeEmail = providers.Factory(SendWelcomeEmail, email_service=email_service)
    AddToCRM = providers.Factory(AddToCRM, repo=user_repo)
    PingHandler = providers.Factory(PingHandler)

container = Container()

# Plug into mediator
def provider(cls):
    try:
        return getattr(container, cls.__name__)()
    except AttributeError:
        return cls()  # fallback empty constructor

mediator._provider = provider

Running with DI

import asyncio

async def main():
    res = await mediator.send(Ping("Hello DI"))
    print("Send result:", res)

    await mediator.publish(UserCreated("Alice"))

if __name__ == "__main__":
    asyncio.run(main())

License

MIT License. See LICENSE for details.

Author: NguyenTungSk

Project details


Download files

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

Source Distribution

mediapyr-0.1.1.tar.gz (3.9 kB view details)

Uploaded Source

Built Distribution

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

mediapyr-0.1.1-py3-none-any.whl (4.8 kB view details)

Uploaded Python 3

File details

Details for the file mediapyr-0.1.1.tar.gz.

File metadata

  • Download URL: mediapyr-0.1.1.tar.gz
  • Upload date:
  • Size: 3.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.11

File hashes

Hashes for mediapyr-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3b1db3037c5c20fc1964ea2e1cff2511fb6cae2ff94869da0cefbacb0d16c6b7
MD5 6a3b108d0c1a1feb54690c7b2d201e4f
BLAKE2b-256 e64836eed4ecfc1e82ff712495c01ddd9ba959210491f87e4b231f04866c9e41

See more details on using hashes here.

File details

Details for the file mediapyr-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: mediapyr-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 4.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.11

File hashes

Hashes for mediapyr-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 151a3995f0546675132d518df326d43d176b4b641f4093453d139e925b573173
MD5 7d5c7fc20a6d4e88a3f2abb6d36ee904
BLAKE2b-256 a608cde952627a4e64a65f8c27507b99cbb5cd1b2f7311093c361c601faf0752

See more details on using hashes here.

Supported by

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