Skip to main content

Yet Another Python Event Emitter

Made in Ukraine license Poetry Ruff pypi Publish Tests codecov Ask DeepWiki

ASAP (as simple as possible), fast, and understandable brokerless, zero-dependent event emitter for Python.

Features

  • Supports both synchronous and asynchronous listeners.
  • Provides event waiting with predicates and optional timeouts.
  • Allows dynamic listener registration and removal.
  • Built-in error propagation and handling.
  • Enables lazy event emission.

Installation

Project published on PyPi under yapee name.

poetry add yapee
pip install yapee
uv add yapee

Usage

Basic Example

import asyncio

from yapee import EventEmitter

ee = EventEmitter()


@ee.enlist("my_event")
def my_listener(data):
    print(f"Received data: {data}")


ee.emit("my_event", "Hello, EventEmitter!")

Asynchronous Listeners

@ee.enlist("async_event")
async def async_listener(data):
    await asyncio.sleep(1)  # Do some async work
    print(f"Async received: {data}")


async def main():
    ee.emit("async_event", "Hello Async!")
    await asyncio.sleep(2)  # Give time for async execution


asyncio.run(main())

Waiting for an Event

async def trigger_event():
    await asyncio.sleep(2)
    ee.emit("wait_event", "Waited data")


asyncio.create_task(trigger_event())
data = await ee.wait_for("wait_event", timeout=5)
print(f"Waited and got: {data}")

Waiting for an Event with Predicate Function

Pay attention that predicate function must be light and do not block execution.

async def trigger_event():
    await asyncio.sleep(2)
    ee.emit("filtered_event", 49)  # Emit event with data, will not pass predicate, as 49 < 50
    await asyncio.sleep(2)
    ee.emit("filtered_event", 51)  # Will pass predicate and wait_for will return 51


asyncio.create_task(trigger_event())

data = await ee.wait_for("filtered_event", predicate=lambda x: x > 50)
print(f"Received matching event data: {data}")

Removing Listeners

# Removing a specific listener
ee.delist("my_event", my_listener)
ee.delist("my_event", async_listener)

# Removing all listeners for an event
ee.delist_all("my_event")

# Removing all listeners for all events
ee.delist_all()

Error Handling in Listeners

By default, any exception inside a listener will be raised. You can override _on_listener_error to customize error handling:

class MyCustomEmitter(EventEmitter):
    async def _on_listener_error(self, event, listener, args, e):
        print(f"Error in listener {listener} for event {event}: {e}")


my_custom_ee = MyCustomEmitter()

Is there anybody interested in this event?

Sometimes emitting an event is cheap, but preparing its payload is not. Use these helpers to check whether an event has any listeners or waiters before doing expensive work:

ee.has_listeners(event)  # at least one listener is registered for event
ee.has_waiters(event)  # at least one active waiter is waiting for event
ee.has_any(event)  # at least one listener or waiter is here awaiting for event

# So
if ee.has_any("my_event"):
    payload = expensive_work()
    ee.emit("my_event", payload)

Release files for yapee 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for yapee 1.0.2
File Size Uploaded
yapee-1.0.2.tar.gz 5.0 kB Details

Built distribution (wheel)

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

Total release size: 10.4 kB

Release files / yapee-1.0.2.tar.gz

Download URL yapee-1.0.2.tar.gz
Size 5.0 kB
Tags Source
SHA-256 checksum
How to use checksums
3f2d17a8caf8b48e3209c2bf76ffe3a046a13b26486c3fe50c0a62a5300b7424
BLAKE2b-256 checksum
How to use checksums
e45ed5fba9b81533aaab1a0eb2a3e35817dbe1c18b25989882d421ceb98b8397
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 23, 2026.

Transparency log

Release files / yapee-1.0.2-py3-none-any.whl

Download URL yapee-1.0.2-py3-none-any.whl
Size 5.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
51a9c31306907a002b0c2b7b7faeec6f2804e74be849f1bb06981d37d1e16462
BLAKE2b-256 checksum
How to use checksums
23a4f28a27c4fc3b7bb9f412a6778e6a35e29bf7454d4ee196ab18fc24e57449
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files

1.0.1

2 release files

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