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.6.tar.gz (4.2 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.6-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mediapyr-0.1.6.tar.gz
  • Upload date:
  • Size: 4.2 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.6.tar.gz
Algorithm Hash digest
SHA256 1e13202b48e085fcfb384b6705c039f4f39c5cf2edbd3503fb9e122080251e7b
MD5 6bebaf9afc230e3064a4a19266381ac9
BLAKE2b-256 d967b771e85aa135bb3430b4baee75a31a1764456728b5bf9f342d5db7aef4ba

See more details on using hashes here.

File details

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

File metadata

  • Download URL: mediapyr-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 5.2 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.6-py3-none-any.whl
Algorithm Hash digest
SHA256 3547b442147b28f8401b171b4344de2b1b313fdf593ae62a84eb8986d8d2d960
MD5 ed5cdacf294204d1e9dc7a05314c33f3
BLAKE2b-256 a6655c24489f131724b3d2b4e973fa32194d9006a17f872ce96c286fa4096ce6

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