Rx-Events
A flexible event-driven system with acknowledgment tracking using Pydantic and ReactiveX.
Features
- ✅ Extensible Event Classes - Create custom event types with Pydantic BaseModel
- ✅ Acknowledgment Tracking - Built-in support for event processing acknowledgments
- ✅ Reactive Streams - Powered by ReactiveX (RxPY) for reactive event processing
- ✅ Type Safety - Full type hints and Pydantic validation
- ✅ Event Bus Pattern - Centralized event management with channels
- ✅ Timeout Handling - Automatic timeout detection and handling
Installation
# Install from local directory (development)
pip install -e /path/to/rx-events
# Or install from source
cd /path/to/rx-events
pip install .
Quick Start
Basic Usage
from rx_events import EventBus, BaseEvent, EventStatus, EventAck
from pydantic import Field
import time
import uuid as uuid_lib
from typing import Dict, Any, Optional
# Create a custom event
class MyEvent(BaseEvent):
user_id: str
data: Dict[str, Any]
uuid: str = Field(default_factory=lambda: str(uuid_lib.uuid4()))
timestamp: float = Field(default_factory=time.time)
correlation_id: Optional[str] = None
@property
def event_type(self) -> str:
return "my_event"
def to_payload(self) -> Dict[str, Any]:
return {"user_id": self.user_id, "data": self.data}
# Create event bus and channel
bus = EventBus()
bus.create_ack_channel("my_channel", timeout_seconds=180)
# Publish event
event = MyEvent(user_id="123", data={"key": "value"})
await bus.publish("my_channel", event)
# Subscribe to events
channel = bus.get_channel("my_channel")
channel.get_event_stream().subscribe(
on_next=lambda event: print(f"Received: {event.event_type}"),
on_error=lambda error: print(f"Error: {error}")
)
# Send acknowledgment
ack = EventAck.create(
event_uuid=event.uuid,
status=EventStatus.COMPLETED,
result={"processed": True}
)
await bus.acknowledge("my_channel", ack)
Custom Event with Validation
from pydantic import Field, field_validator
class UserEvent(BaseEvent):
user_id: str
email: str
uuid: str = Field(default_factory=lambda: str(uuid_lib.uuid4()))
timestamp: float = Field(default_factory=time.time)
correlation_id: Optional[str] = None
@field_validator('email')
@classmethod
def validate_email(cls, v: str) -> str:
if '@' not in v:
raise ValueError("Invalid email")
return v
@property
def event_type(self) -> str:
return "user_event"
def to_payload(self) -> Dict[str, Any]:
return {"user_id": self.user_id, "email": self.email}
Testing
Run tests with pytest:
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=rx_events --cov-report=html
API Reference
Core Classes
BaseEvent- Abstract base class for custom eventsEvent- Standard event class for general-purpose eventsBaseEventAck- Abstract base class for custom acknowledgmentsEventAck- Standard acknowledgment classEventStatus- Enum for event statuses (PENDING, PROCESSING, COMPLETED, FAILED, TIMEOUT)EventBus- Central event bus for managing channelsAckChannel- Channel for event publishing and acknowledgment tracking
EventBus Methods
create_ack_channel(name, allow_duplicates=False, timeout_seconds=300)- Create a new acknowledgment channelget_channel(name)- Get an existing channelpublish(channel_name, event)- Publish an event to a channelacknowledge(channel_name, ack)- Send an acknowledgment
AckChannel Methods
publish(event)- Publish an eventacknowledge(ack)- Receive an acknowledgmentget_event_stream()- Get ReactiveX Observable for eventsget_ack_stream()- Get ReactiveX Observable for acknowledgmentsget_stats()- Get channel statisticsget_event_status(event_uuid)- Get status of a specific event
Examples
See the tests/ directory for comprehensive examples.
License
MIT
Metadata
Release files for rx-events 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| rx_events-0.1.1.tar.gz | 111.1 kB | Without provenance | Details for rx_events-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| rx_events-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for rx_events-0.1.1-py3-none-any.whl |
Total release size: 119.6 kB
Release files / rx_events-0.1.1.tar.gz
| Download URL | rx_events-0.1.1.tar.gz |
|---|---|
| Size | 111.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9cc542f64cc0e7ae81b234a866ac4abd99dab6609cf6f7ecf3828fb681ec1801
|
|
BLAKE2b-256 checksum How to use checksums |
8cbee43e3ba9054f7b8159ec330075d81fdc3e0971f8172447cea91f5a06788c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.13
|
Release files / rx_events-0.1.1-py3-none-any.whl
| Download URL | rx_events-0.1.1-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
efb01a6b611291616a05a43c153f38db7fb23f24963fb8c641bd0be8e2a541cc
|
|
BLAKE2b-256 checksum How to use checksums |
cb31f59af9f29e6c42c2e9397e71a8ba3a39ec4c5f3684a710c152b6baaa3ea5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.13
|
Security for rx-events 0.1.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.