Skip to main content

PyEventEngine

High-performance, topic-driven event engine for Python with a Cython-accelerated core and a native Python fallback.

  • Fast publish/subscribe event routing by topic (exact + generic wildcard/pattern matching)
  • Clean, typed API with drop-in fallback when C extensions are unavailable
  • Built-in timers, handler stats (EventHookEx), and convenient formatting helpers

Installation

# From PyPI (pre-compiled wheels available)
pip install PyEventEngine

# From source (requires C compiler + Cython ≥ 3.0)
git clone https://github.com/BolunHan/PyEventEngine.git
cd PyEventEngine

# Build + install
./build.sh -i

# Or via Makefile:
make build && pip install -U . --no-build-isolation

# Or step by step:
python setup.py build_ext --inplace --verbose --force
pip install -U . --no-build-isolation

See the Installation Guide for platform-specific prerequisites, compile-time macros, and troubleshooting.

Quick Start

import time
from event_engine import EventEngine, Topic

# Create and start the engine
engine = EventEngine(capacity=8192)
engine.start()

# Register a handler for an exact topic
exact = Topic('Demo.Hello')

def hello_handler(name: str, topic=None):
    print(f"Hello {name} from {topic.value if topic else 'N/A'}")

engine.register_handler(exact, hello_handler)

# Publish a message
engine.put(exact, 'World')

# Clean up
time.sleep(0.1)
engine.stop()
engine.clear()

Generic topics (wildcards/patterns)

import time
from event_engine import Topic, EventEngine

engine = EventEngine()
pattern = Topic('Demo.{what}')

calls = []

def f(what: str, topic=None):
    calls.append((what, topic.value))

engine.register_handler(pattern, f)

engine.start()
engine.put(Topic('Demo.Test'), 'a test sub-topic')
engine.put(Topic('Demo.Live'), 'a live sub-topic')
time.sleep(0.1)  # allow time for processing
engine.stop()

print(calls)  # [('a test sub-topic', 'Demo.Test'), ('a live sub-topic', 'Demo.Live')]

Timers (EventEngineEx)

import time
from event_engine import EventEngineEx, Topic

engine = EventEngineEx(capacity=4096)
engine.start()

# Create a 1-second timer topic and subscribe
timer_topic = engine.get_timer(1.0)
engine.register_handler(timer_topic, lambda **kw: print('tick', kw))

time.sleep(3)
engine.stop()
engine.clear()

Logging

By default, the package uses a colored logger under event_engine.base. To integrate with your application's logging, call set_logger once after import — it propagates to submodules.

import logging
from event_engine import set_logger

logger = logging.getLogger('MyApp')
logger.setLevel(logging.INFO)
set_logger(logger)

Fallback behavior

On import, the package tries to use the Cython implementation (event_engine.capi). If that fails (e.g., no compiler available), it automatically falls back to the native Python implementation (event_engine.native). Check the active backend:

from event_engine import USING_FALLBACK
print('Using native fallback?', USING_FALLBACK)

Development

# Clone and build in-place
git clone https://github.com/BolunHan/PyEventEngine.git
cd PyEventEngine
./build.sh -i

# Run tests
python -m pytest demo/

# Performance benchmarks
python demo/native_performance_test.py
python demo/capi_performance_test.py       # requires compiled extensions

Build scripts

Command Effect
./build.sh -i Clean + build + install
./build.sh -l List compile-time macros
make build Clean + build in-place
make clean-all Deep clean (removes .c/.so)

Documentation

Full documentation: https://bolunhan.github.io/PyEventEngine/

Build locally:

pip install sphinx furo sphinx-autodoc-typehints
cd docs
sphinx-build -M html . _build
# Open _build/html/index.html

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

pyeventengine-0.6.0.post1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pyeventengine-0.6.0.post1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pyeventengine-0.6.0.post1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pyeventengine-0.6.0.post1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

File details

Details for the file pyeventengine-0.6.0.post1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyeventengine-0.6.0.post1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1756de3f33e2887e6d174e9307e0b54b200a0e5e2debde79e3dc1bf69bc1a97d
MD5 1c5e36a9357fa871d18fc6ca975bb8a8
BLAKE2b-256 05666c7032af20cacb1907b83ec73c78096799a83d3051e1a7022eabe9b610c6

See more details on using hashes here.

File details

Details for the file pyeventengine-0.6.0.post1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyeventengine-0.6.0.post1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 416efa8c99566e7c4aaf16e79aeac921843e49b3d6a2bcb31ba398ece7d8cc30
MD5 e87305c64481e537568df40e178f14e6
BLAKE2b-256 43fc92c215e2be626ec65ec6def9d91ac43c85856d58ede43be9754889c973d4

See more details on using hashes here.

File details

Details for the file pyeventengine-0.6.0.post1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyeventengine-0.6.0.post1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c9e2492e21ce002e64f6cdc256f65c31f3a5fc4cf94a556723ae7c0d9857067c
MD5 5c522582c4b83a9f1135e017828ea76d
BLAKE2b-256 57d653f0ac74d539bafd3c18f86a743319d380e84166b00b0635a9936d3d91c5

See more details on using hashes here.

File details

Details for the file pyeventengine-0.6.0.post1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyeventengine-0.6.0.post1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0b6c3ff4e06e4dc88522137b632a6ffef26c899725f813a44a59189a781b7496
MD5 5ccb0565df7a821bd97630f185f50b95
BLAKE2b-256 ac37889bea800dd311f3cc25d3a7b54a9c371c586b51a6c384711c7ce127e77e

See more details on using hashes here.

Release history Release notifications | RSS feed

1.0.2

12 files

1.0.1

6 files

1.0.0

6 files

0.6.2.post1

12 files

0.6.2

12 files

0.6.0.post3

8 files

0.6.0.post2

4 files

This release

0.6.0.post1 This release

4 files

0.6.0

4 files

0.5.2.post3

4 files

0.5.2.post1

4 files

0.5.2

4 files

0.5.1.post1

4 files

0.5.1

4 files

0.5.0.post2

4 files

0.5.0.post1

4 files

0.4.6.post1

4 files

0.4.6

4 files

0.4.5

4 files

0.4.4.post1

4 files

0.4.4

4 files

0.3.2

2 files

0.3.0.post5

1 file

0.3.0.post4

1 file

0.3.0.post3

1 file

0.3.0.post2

1 file

0.3.0.post1

1 file

0.3.0

1 file

0.2.1

1 file

0.1.4

1 file

0.1.2

1 file

0.1.1

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page