Take control of your event routing.
Project description
Power-Events
Source Code: https://github.com/MLetrone/power-events
documentation: https://mletrone.github.io/power-events
Take control of your event routing, effortlessly and tailored to your needs.
Description
Power-events is a lightweight yet powerful library that manages event routing by defining routes with precise conditions, inspired by FastAPI’s endpoint routing system. It simplifies the organization of complex events by applying specific routing rules defined by the user and enables actions to be triggered in response to events in a structured manner.
Key features:
- Syntax: Lean to standards like Powertools or FastAPI.
- Easy: Design to be easy to read and use.
- Flexible: You can do whatever condition at any depth level in your event.
- Modular routing: Split routes across
EventRouterinstances and compose them into oneEventResolver. - Event converter: Transform raw events into typed objects (dataclass, Pydantic model, …) before they reach your handlers.
- Parallel execution: Matching routes are executed concurrently for maximum throughput.
- Fully tested: 100% coverage.
- Fully typed: compatible out of the box with
mypy! - Lightweight
installation
pip install power-events
That's all! Ready to use
Examples
Simple conditions
- create a
main.pywith:
from typing import Any
from power_events import EventResolver
app = EventResolver()
@app.equal("type", "order_created")
def handler_order_created(event: dict[str, Any]) -> str:
return f"Order created: {event['order_id']}"
@app.one_of("type", ["order_update", "order_delete"])
def handle_order_modification(event: dict[str, Any]) -> str:
return f"Order modification <{event['type']}>: {event['order_id']}"
- use routing:
N.B: assert is here to show which route has been called. In real condition, don't need to use it.
assert app.resolve({
"type": "order_created",
"order_id": "12345",
"user_id": "67890"
}) == ["Order created: 12345"]
# Note: `resolve` returns a list, because you can allow multiple routes for one event.
assert app.resolve({
"type": "order_delete",
"order_id": "12345",
"user_id": "67890"
})== ["Order modification <order_delete>: 12345"]
Complex conditions
In depth field condition and condition combinations
from power_events import EventResolver
from power_events.conditions import Value, Neg
app = EventResolver()
# Order created and digital purchase.
@app.when(Value("type").equals("order_created") & Value("cart.is_digital").is_truthy())
def handle_digital_purchase(event: dict) -> str:
return f"The order created is a digital purchase: {event['order_id']}"
# Order created and physical.
@app.when(Value("type").equals("order_created") & Neg(Value("cart.is_digital").is_truthy()))
def handle_physical_purchase(event: dict) -> str:
return f"The order created is a physical purchase: {event['order_id']}"
assert app.resolve({
"type": "order_created",
"order_id": "12345",
"user_id": "67890",
"cart": {
"is_digital": True,
"items": [
"$10 voucher"
]
}
}) == ["The order created is a digital purchase: 12345"]
assert app.resolve({
"type": "order_created",
"order_id": "12345",
"user_id": "67890",
"cart": {
"is_digital": False,
"items": [
"keyboard"
]
}
}) == ["The order created is a physical purchase: 12345"]
It's possible to perform OR, AND, NEG operation over conditions.
Modular routing with EventRouter
Split routes across dedicated routers and compose them into one resolver
from power_events import EventResolver, EventRouter
from power_events.conditions import Value
order_router = EventRouter()
@order_router.equal("type", "order_created")
def handle_order_created(event: dict) -> str:
return f"Order created: {event['order_id']}"
@order_router.equal("type", "order_deleted")
def handle_order_deleted(event: dict) -> str:
return f"Order deleted: {event['order_id']}"
user_router = EventRouter()
@user_router.equal("type", "user_created")
def handle_user_created(event: dict) -> str:
return f"User created: {event['user_id']}"
app = EventResolver()
app.include_router(order_router, base_condition=Value("service").equals("order"))
app.include_router(user_router, base_condition=Value("service").equals("user"))
assert app.resolve({
"service": "order",
"type": "order_created",
"order_id": "12345",
}) == ["Order created: 12345"]
assert app.resolve({
"service": "user",
"type": "user_created",
"user_id": "67890",
}) == ["User created: 67890"]
Project details
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 power_events-2.0.0.tar.gz.
File metadata
- Download URL: power_events-2.0.0.tar.gz
- Upload date:
- Size: 92.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28b3d44c52cce47de1c4c6e1b7c99f5e58f3139335098c21df3520cf6c022400
|
|
| MD5 |
0f8a26a57dff066240344407059af143
|
|
| BLAKE2b-256 |
7adbfbd9249d251f6fa5d18bdb1ffc2059d2429c0ca572f14fefd4a6cf3754ce
|
Provenance
The following attestation bundles were made for power_events-2.0.0.tar.gz:
Publisher:
release.yml on mLetrone/power-events
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
power_events-2.0.0.tar.gz -
Subject digest:
28b3d44c52cce47de1c4c6e1b7c99f5e58f3139335098c21df3520cf6c022400 - Sigstore transparency entry: 1823254197
- Sigstore integration time:
-
Permalink:
mLetrone/power-events@88279048bda26bae285db16e0eb7fe2da89590f7 -
Branch / Tag:
refs/tags/2.0.0 - Owner: https://github.com/mLetrone
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@88279048bda26bae285db16e0eb7fe2da89590f7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file power_events-2.0.0-py3-none-any.whl.
File metadata
- Download URL: power_events-2.0.0-py3-none-any.whl
- Upload date:
- Size: 14.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3f9e441bd232e42089522e724a5b4d6f1886a7ce1a9c39cfdfc1484c1b30fa3
|
|
| MD5 |
75bc14592ad33776115696288578b51b
|
|
| BLAKE2b-256 |
62e4a40b7583779f0e73dbc6e4d1d7cd253c55c6b2a694a53c86cae17eaef19d
|
Provenance
The following attestation bundles were made for power_events-2.0.0-py3-none-any.whl:
Publisher:
release.yml on mLetrone/power-events
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
power_events-2.0.0-py3-none-any.whl -
Subject digest:
e3f9e441bd232e42089522e724a5b4d6f1886a7ce1a9c39cfdfc1484c1b30fa3 - Sigstore transparency entry: 1823254272
- Sigstore integration time:
-
Permalink:
mLetrone/power-events@88279048bda26bae285db16e0eb7fe2da89590f7 -
Branch / Tag:
refs/tags/2.0.0 - Owner: https://github.com/mLetrone
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@88279048bda26bae285db16e0eb7fe2da89590f7 -
Trigger Event:
push
-
Statement type: