Yet Another Python Event Emitter
Project description
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)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file yapee-1.0.2.tar.gz.
File metadata
- Download URL: yapee-1.0.2.tar.gz
- Upload date:
- Size: 5.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f2d17a8caf8b48e3209c2bf76ffe3a046a13b26486c3fe50c0a62a5300b7424
|
|
| MD5 |
2126a099cfc6183ba8afb856bd2229de
|
|
| BLAKE2b-256 |
e45ed5fba9b81533aaab1a0eb2a3e35817dbe1c18b25989882d421ceb98b8397
|
Provenance
The following attestation bundles were made for yapee-1.0.2.tar.gz:
Publisher:
publish.yml on somespecialone/yapee
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
yapee-1.0.2.tar.gz -
Subject digest:
3f2d17a8caf8b48e3209c2bf76ffe3a046a13b26486c3fe50c0a62a5300b7424 - Sigstore transparency entry: 982768940
- Sigstore integration time:
-
Permalink:
somespecialone/yapee@ce144444154fd83961cd7e6b837cc4ff13fac27d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/somespecialone
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ce144444154fd83961cd7e6b837cc4ff13fac27d -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file yapee-1.0.2-py3-none-any.whl.
File metadata
- Download URL: yapee-1.0.2-py3-none-any.whl
- Upload date:
- Size: 5.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51a9c31306907a002b0c2b7b7faeec6f2804e74be849f1bb06981d37d1e16462
|
|
| MD5 |
8c0fc2463d4946eccc7b984efeef60f4
|
|
| BLAKE2b-256 |
23a4f28a27c4fc3b7bb9f412a6778e6a35e29bf7454d4ee196ab18fc24e57449
|
Provenance
The following attestation bundles were made for yapee-1.0.2-py3-none-any.whl:
Publisher:
publish.yml on somespecialone/yapee
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
yapee-1.0.2-py3-none-any.whl -
Subject digest:
51a9c31306907a002b0c2b7b7faeec6f2804e74be849f1bb06981d37d1e16462 - Sigstore transparency entry: 982768945
- Sigstore integration time:
-
Permalink:
somespecialone/yapee@ce144444154fd83961cd7e6b837cc4ff13fac27d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/somespecialone
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ce144444154fd83961cd7e6b837cc4ff13fac27d -
Trigger Event:
workflow_run
-
Statement type: