Yet Another Python Event Emitter
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)
| File | Size | Uploaded | |
|---|---|---|---|
| yapee-1.0.2.tar.gz | 5.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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