Skip to main content

Eventry

Eventry is a dependency-free Python library for asynchronous, in-process event routing and processing.

Eventry lets you create customizable routers for your own framework or application, or use the built-in default router for simpler use cases. It supports middleware and filters at every routing level: routers, handler managers, and individual handlers.

Installation

pip install eventry

Using built-in components

For simple use cases you can use built-in Dispatcher, DefaultRouter and DefaultHandlerManager.

from eventry.asyncio import Dispatcher, DefaultRouter, ExtendedEvent


router = DefaultRouter(name='my_router')
dp = Dispatcher(router)


# Let's create some custom event.
class MyEvent(ExtendedEvent, event_name='my_event'):
    def __init__(self, trigger: str):
        super().__init__()
        self.trigger = trigger


# Default router has only one handler manager that does not filter events and accepts all of them.
# Type annotations don't filter events.
@router.on_event()
async def my_handler(event: ExtendedEvent) -> None:
    print(event.__event_name__)


# If you want to filter events by type without creating custom routers, you can use handler filters.
@router.on_event(lambda event: event.name == 'my_event')
async def my_handler_with_filter(event: MyEvent):
    print(event.trigger)


async def main():
    my_event = MyEvent('qvvonk')
    await dp.propagate_event(my_event)  # both handlers will be executed.

    event = ExtendedEvent()
    await dp.propagate_event(event)  # only `my_handler` will be executed.


if __name__ == '__main__':
    import asyncio

    asyncio.run(main())

Creating custom routers

Eventry lets you create your custom routers. Note: unlike DefaultRouter, the base Router has no HandlerManager's or MiddlewareStorage's.

import asyncio

from eventry.asyncio import Router, DefaultHandlerManager, MiddlewareStorage, ExtendedEvent


class ApplicationRouter(Router):
    def __init__(self, name: str = ''):
        super().__init__(name=name)

        self.on_new_message = self.add_handler_manager(
            DefaultHandlerManager(name='on_message', event_filter='new_message')
        )

        self.on_new_order = self.add_handler_manager(
            DefaultHandlerManager(name='on_order', event_filter='new_order')
        )

    @property
    def outer_middleware(self) -> MiddlewareStorage:
        return self.middleware.get_middlewares_storage('router.outer', raise_=True)

    @property
    def inner_middleware(self) -> MiddlewareStorage:
        return self.middleware.get_middlewares_storage('router.inner', raise_=True)


# Now lets create our custom events.
class NewMessageEvent(ExtendedEvent, event_name='new_message'):
    def __init__(self, message: str):
        super().__init__()
        self.message = message


class NewOrderEvent(ExtendedEvent, event_name='new_order'):
    def __init__(self, order_id: int):
        super().__init__()
        self.order_id = order_id


# Now we can use new router and events in our application.
from eventry.asyncio import Dispatcher


router = ApplicationRouter(name='my_router')
dp = Dispatcher(router)


@router.on_new_message()
async def print_message(event: NewMessageEvent) -> None:
    print(event.message)


@router.on_new_order()
async def print_order_id(event: NewOrderEvent) -> None:
    print(event.order_id)


async def main():
    await dp.propagate_event(NewMessageEvent('Hello World!'))
    await dp.propagate_event(NewOrderEvent(12345))


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

Metadata

Release files for eventry 0.7.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 eventry 0.7.0
File Size Uploaded Provenance Actions
eventry-0.7.0.tar.gz 18.6 kB Without provenance Details for eventry-0.7.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for eventry 0.7.0
File Interpreter ABI Platform Actions
eventry-0.7.0-py3-none-any.whl Python 3 none any Details for eventry-0.7.0-py3-none-any.whl

Total release size: 42.8 kB

Release files / eventry-0.7.0.tar.gz

Download URL eventry-0.7.0.tar.gz
Size 18.6 kB
Tags Source
SHA-256 checksum
How to use checksums
edf4fc1b55b2674907c83f435de76c5661df3ae63da9edb58d8fb9bdb11abe56
BLAKE2b-256 checksum
How to use checksums
f4ae261fcdd05795b1cee92610d66c2a5cbca06992c76554270aa48fd56f0ab3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.5.30

Release files / eventry-0.7.0-py3-none-any.whl

Download URL eventry-0.7.0-py3-none-any.whl
Size 24.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d4485ee129629697a49704324b5e7d7d324e55648c6fe5723e70f99d29009cbc
BLAKE2b-256 checksum
How to use checksums
b1d39d8b42963de3c12f148ddda8c422902a98e3edf846538502bdead971fd7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.5.30

Security for eventry 0.7.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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