Skip to main content

A lightweight Python package for dynamically generating event decorators and trigger functions

Project description

EventRaisers (eventraisers) - Dynamic Event System for Python

PyPI version Python versions License

EventRaisers (formerly "py-event-raiser-generator") is a lightweight, zero-dependency Python library that dynamically generates event decorators and trigger functions at runtime. Define your events once, and EventRaisers automatically creates the necessary infrastructure for event registration and triggering.

Key Features

🚀 Dynamic Generation - Automatically create event decorators and trigger functions from simple definitions

Zero Dependencies - Built entirely on Python's standard library (typing, inspect)

🔧 Type Annotated - Full type hint support for better IDE integration and code clarity

🔄 Async/Sync Support - Handle both synchronous and asynchronous callback functions

Event Scheduling - Built-in priority-based event scheduling system

🐍 Python 3.9+ - Compatible with Python 3.9 through 3.14

Quick Start

from eventraisers import EventDict, generate_event_raisers

# Define your events
EVENTS: EventDict = {
    "user_login": [("user_id", int), ("timestamp", float)],
    "order_placed": [("order_id", str), ("total_amount", float)]
}

# Generate decorators and trigger functions
generate_event_raisers(EVENTS, globals())

# Register event handlers
@user_login
def handle_login(user_id: int, timestamp: float) -> None:
    print(f"User {user_id} logged in at {timestamp}")

# Trigger events
raise_user_login(user_id=123, timestamp=1718987654.123)

Installation

From PyPI (Recommended)

pip install eventraisers

From Source

git clone https://github.com/Pac-Dessert1436/py-event-raiser-generator.git
cd py-event-raiser-generator
pip install .

Usage Guide

1. Define Your Events

Start by defining your events as a dictionary mapping event names to parameter specifications.

from eventraisers import EventDict, generate_event_raisers

# Define events with their parameter names and types
EVENTS: EventDict = {
    "user_login": [("user_id", int), ("timestamp", float)],
    "order_placed": [("order_id", str), ("total_amount", float)],
    "system_alert": [("message", str), ("severity", str)]
}

# Generate the event infrastructure
generate_event_raisers(EVENTS, globals())

2. Register Event Handlers

Use the generated decorators to register callback functions for your events.

# Register synchronous handlers
@user_login
def handle_user_login(user_id: int, timestamp: float) -> None:
    print(f"User {user_id} logged in at {timestamp}")

@order_placed  
def handle_order_placed(order_id: str, total_amount: float) -> None:
    print(f"Order {order_id} placed (total: ${total_amount:.2f})")

# Register asynchronous handlers (Python 3.5+)
@system_alert
async def handle_system_alert(message: str, severity: str) -> None:
    print(f"[{severity.upper()}] {message}")

3. Trigger Events

Use the generated raise_* functions to trigger your events.

# Trigger events with parameters
raise_user_login(user_id=123, timestamp=1718987654.123)
raise_order_placed(order_id="ORD-9876", total_amount=49.99)
raise_system_alert(message="Database connection lost", severity="error")

4. Event Registry Management

Manage registered callbacks and clear the event registry when needed.

from eventraisers import get_event_registry, clear_event_registry

# Inspect registered callbacks
registry = get_event_registry()
print(f"Registered 'user_login' callbacks: {len(registry.get('user_login', []))}")

# Clear all registered callbacks
clear_event_registry()

5. Event Scheduling

Schedule events with priority-based execution using the EventScheduler class.

from eventraisers import EventScheduler
from time import sleep

scheduler = EventScheduler()

# Schedule events with different priorities
scheduler.schedule_event_action(
    lambda: raise_user_login(user_id=123, timestamp=1718987654.123), 
    priority=30
)
scheduler.schedule_event_action(
    lambda: print("Medium priority event"), 
    priority=50
)
scheduler.schedule_event_action(
    lambda: print("High priority event"), 
    priority=80
)

# Execute all scheduled events in priority order
scheduler.raise_scheduled_events()
print(f"Pending events: {scheduler.pending_event_count}")

Advanced Features

Type Checking Support

For better IDE integration and type checking, you can provide stub definitions before generating events:

from eventraisers import EventOf, EventDict, generate_event_raisers

EVENTS: EventDict = {
    "user_login": [("user_id", int), ("timestamp", float)],
    "order_placed": [("order_id", str), ("total_amount", float)]
}

# Stub definitions for type checkers
def user_login(func: EventOf[int, float]) -> EventOf[int, float]: ...
def order_placed(func: EventOf[str, float]) -> EventOf[str, float]: ...
def raise_user_login(user_id: int, timestamp: float) -> None: ...
def raise_order_placed(order_id: str, total_amount: float) -> None: ...

# Generate the actual implementation
generate_event_raisers(EVENTS, globals())

Error Handling

EventRaisers provides graceful error handling - exceptions in callbacks don't interrupt other handlers:

@user_login
def problematic_handler(user_id: int, timestamp: float) -> None:
    raise ValueError("Something went wrong!")

@user_login  
def working_handler(user_id: int, timestamp: float) -> None:
    print(f"User {user_id} handled successfully")

# Both handlers are called, errors are logged but don't stop execution
raise_user_login(user_id=123, timestamp=1718987654.123)
# Output: [NOTICE] Error in event 'user_login': Something went wrong!
# Output: User 123 handled successfully

API Reference

Core Functions

generate_event_raisers(events: EventDict, module_globals: dict[str, Any]) -> None

Generates event decorators and trigger functions based on the provided event definitions.

Parameters:

  • events: Dictionary mapping event names to parameter specifications
  • module_globals: Global namespace (use globals() to add functions to current scope)

clear_event_registry() -> None

Clears all registered event callbacks from the internal registry.

get_event_registry() -> dict[str, list[Callable[..., Any | Awaitable[Any]]]]

Returns the current event registry as a dictionary mapping event names to lists of registered callbacks.

Type Aliases

EventOf: TypeAlias = Callable[[Unpack[_Args]], None | Awaitable[None]]

Generic type for event callback functions, supporting both synchronous and asynchronous handlers.

EventDict: TypeAlias = dict[str, list[tuple[str, Any]]]

Type for event definition dictionaries (event name → parameter specifications).

EventScheduler Class

Priority-based event scheduling system.

EventScheduler()

Creates a new event scheduler instance.

schedule_event_action(event_action: Callable[[], None], priority: int = 0) -> None

Schedules an event action with the specified priority (higher numbers execute first).

raise_scheduled_events() -> None

Executes all scheduled events in priority order.

pending_event_count: int (property)

Returns the number of pending events in the scheduler.

Use Cases

EventRaisers is ideal for:

  • Plugin Systems - Allow plugins to register event handlers
  • Game Development - Handle game events like collisions, achievements, etc.
  • Web Applications - Process user actions, notifications, and system events
  • IoT Applications - Handle sensor data and device state changes
  • Microservices - Coordinate actions between different service components

Best Practices

  1. Define events early - Generate event infrastructure at module initialization
  2. Use descriptive event names - Make events self-documenting
  3. Provide type stubs - For better IDE support and type checking
  4. Handle errors gracefully - Use the built-in error handling for robust applications
  5. Clear registry when needed - Use clear_event_registry() for cleanup

Known Limitations

  • Type Checker Support: Generated functions may not be fully recognized by static type checkers
  • Global Namespace: Functions are added to the provided namespace, which may cause conflicts
  • Dynamic Nature: Runtime generation means some IDE features may not work perfectly

Contributing

Contributions are welcome! Please feel free to:

  1. Open an issue to report bugs or suggest features
  2. Submit a pull request with improvements
  3. Help improve type checking support
  4. Add more examples and documentation

License

EventRaisers is released under the MIT License. See the LICENSE file for details.


EventRaisers - Simplify your event-driven programming in Python! 🚀

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

eventraisers-1.0.0.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eventraisers-1.0.0-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

File details

Details for the file eventraisers-1.0.0.tar.gz.

File metadata

  • Download URL: eventraisers-1.0.0.tar.gz
  • Upload date:
  • Size: 9.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for eventraisers-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0fcc0d39bc23d59b66213799b99b6d1a061fef69a1fbe3486e72562036a6f6e8
MD5 028b22ebc8315c380542a31a8696bb5e
BLAKE2b-256 23b39f41e92e89e7e9a49f01e2507eb26a037225d8715a46bfe410eab50f35a2

See more details on using hashes here.

File details

Details for the file eventraisers-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: eventraisers-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 8.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for eventraisers-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 692b395d5282a81611820c85bfd852869209d64b74b39d6b81fa14845f57975b
MD5 65c821459c4f00dcc6b687d7b2d07040
BLAKE2b-256 a38382c70c30e7e64a1eb8d2e71bf34b29cf1dbcf414ed8150a99d86f44d6618

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page