emitix
Lightweight event bus for Python applications. No dependencies, fully typed, works with both sync and async code.
pip install emitix
Quick start
import emitix
@emitix.on("user.created")
def send_welcome_email(user):
print(f"Welcome, {user}!")
emitix.emit("user.created", "Ada")
# Welcome, Ada!
The module-level functions use one shared bus. Create your own when you want separate buses:
from emitix import EventBus
bus = EventBus()
bus.on("order.paid", lambda order_id: print("paid", order_id))
bus.emit("order.paid", 42)
Features
Any arguments
Whatever you pass to emit is passed to the handlers, and emit returns their results.
bus.on("add", lambda a, b: a + b)
bus.emit("add", 2, 3) # [5]
Wildcards
Subscriptions accept shell-style patterns (*, ?, [abc]). Use pass_event=True to receive the event name as the first argument.
@bus.on("user.*", pass_event=True)
def audit(event, user):
print(event, user)
bus.emit("user.created", "Ada") # user.created Ada
bus.emit("user.deleted", "Ada") # user.deleted Ada
One-shot handlers
@bus.once("app.ready")
def warm_cache():
...
Priorities
Higher priority runs first. Handlers with the same priority run in the order they were registered.
bus.on("save", validate, priority=10)
bus.on("save", write_to_disk)
Async handlers
emit_async awaits async def handlers and calls regular ones normally. Handlers run one after another, in priority order.
@bus.on("job.done")
async def notify(job_id):
await send_notification(job_id)
await bus.emit_async("job.done", 7)
Calling plain emit for an event that has an async handler raises TypeError.
Unsubscribing
bus.off("save", write_to_disk) # remove one handler
bus.off("save") # remove every handler for "save"
bus.clear() # remove everything
API
| Method | Description |
|---|---|
on(event, handler=None, *, priority=0, once=False, pass_event=False) |
Subscribe a handler. Works as a decorator when handler is omitted. |
once(event, handler=None, *, priority=0, pass_event=False) |
Subscribe a handler for a single call. |
off(event, handler=None) |
Remove one handler, or all handlers for event. Returns the number removed. |
emit(event, *args, **kwargs) |
Call the matching handlers and return a list of their results. |
emit_async(event, *args, **kwargs) |
Same as emit, but awaits async handlers. |
listeners(event) |
Handlers that would run for event, in call order. |
clear() |
Remove every subscription. |
An exception raised by a handler propagates to the caller of emit and stops the remaining handlers. All methods are thread-safe.
Development
pip install -e ".[dev]"
pytest
License
MIT
Metadata
Release files for emitix 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| emitix-0.1.0.tar.gz | 6.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| emitix-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.2 kB
Release files / emitix-0.1.0.tar.gz
| Download URL | emitix-0.1.0.tar.gz |
|---|---|
| Size | 6.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
66168231d813dae0224f00ef476f7febf85ad41110c73939258142159fb724f3
|
|
BLAKE2b-256 checksum How to use checksums |
0edf895298d8358fdb60d4048c7afeb6c0ee56ff171301a1ceec9c7abd2238f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / emitix-0.1.0-py3-none-any.whl
| Download URL | emitix-0.1.0-py3-none-any.whl |
|---|---|
| Size | 6.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c769f9f67ab5272e6a20c1a4ef0aa4aec82609bf71e4e56261262193d9104558
|
|
BLAKE2b-256 checksum How to use checksums |
7c4d9d811c3b22d11922cc78d4f8744eb9a289ff604f8b44bdca8a85f10102ac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|