Current collected state Current
Observed since 20 Oct, 20:58 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Event-driven data pipelines
|Build| |PyVersion| |Status| |PyPiVersion| |License| |Docs|
Introduction
------------
The primary use cases of eventkit are
* to send events between loosely coupled components;
* to compose all kinds of event-driven data pipelines.
The interface is kept as Pythonic as possible,
with familiar names from Python and its libraries where possible.
For scheduling asyncio is used and there is seamless integration with it.
See the examples and the
`introduction notebook <https://github.com/ib-api-reloaded/eventkit/tree/main/notebooks/eventkit_introduction.ipynb>`_
to get a true feel for the possibilities.
Note: the package is published as ``aeventkit`` and imported as ``eventkit``.
Installation
------------
::
pip install aeventkit
pip install aeventkit[numpy] # with the Array operators
Python_ 3.11 or later is required (tested on CPython 3.11 to 3.15 and
PyPy 3.11).
Upgrading from 2.x? See `Upgrading to 3.0
<https://eventkit.readthedocs.io/en/latest/upgrading.html>`_ and the
`changelog <https://eventkit.readthedocs.io/en/latest/changelog.html>`_.
Examples
--------
**Create an event and connect two listeners**
.. code-block:: python
import eventkit as ev
def f(a, b):
print(a * b)
def g(a, b):
print(a / b)
event = ev.Event()
event += f
event += g
event.emit(10, 5)
**Create a simple pipeline**
.. code-block:: python
import eventkit as ev
event = (
ev.Sequence('abcde')
.map(str.upper)
.enumerate()
)
print(event.run()) # in Jupyter: await event.list()
Output::
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D'), (4, 'E')]
**Create a pipeline to get a running average and standard deviation**
(with the numpy extra: ``pip install aeventkit[numpy]``)
.. code-block:: python
import random
import eventkit as ev
source = ev.Range(1000).map(lambda i: random.gauss(0, 1))
event = source.array(500)[ev.ArrayMean, ev.ArrayStd].zip()
print(event.last().run()) # in Jupyter: await event.last()
Output::
[(0.00790957852672618, 1.0345673260655333)]
**Combine async iterators together**
.. code-block:: python
import asyncio
import eventkit as ev
async def ait(r):
for i in r:
await asyncio.sleep(0.1)
yield i
async def main():
async for t in ev.Zip(ait('XYZ'), ait('123')):
print(t)
asyncio.run(main()) # in Jupyter: await main()
Output::
('X', '1')
('Y', '2')
('Z', '3')
**Real-time video analysis pipeline**
.. code-block:: python
self.video = VideoStream(conf.CAM_ID)
scene = self.video | FaceTracker | SceneAnalyzer
lastScene = scene.aiter(skip_to_last=True)
async for frame, persons in lastScene:
...
`Full source code <https://github.com/erdewit/heartwave/blob/100e1a89d18756e141f9dcfbb73c55a1009debf4/heartwave/app.py#L88>`_
Parallel processing
-------------------
``poolmap`` runs a function on the values of an event in a
``concurrent.futures`` executor: a process pool for CPU-bound work on all
cores, an interpreter pool (Python 3.14+), or a thread pool for blocking
I/O. Results stay in order unless ``ordered=False``, and ``chunksize``
batches small tasks:
.. code-block:: python
import bz2
from concurrent.futures import ProcessPoolExecutor
import eventkit as ev
if __name__ == "__main__":
data = [b"A" * 1_000_000] * 1000
with ProcessPoolExecutor() as pool:
sizes = ev.Sequence(data).poolmap(pool, bz2.compress, chunksize=10).map(len)
print(sizes.mean().last().run())
Inspired by:
------------
* `Qt Signals & Slots <https://doc.qt.io/qt-5/signalsandslots.html>`_
* `itertools <https://docs.python.org/3/library/itertools.html>`_
* `aiostream <https://github.com/vxgmichel/aiostream>`_
* `Bacon <https://baconjs.github.io/index.html>`_
* `aioreactive <https://github.com/dbrattli/aioreactive>`_
* `Reactive extensions <http://reactivex.io/documentation/operators.html>`_
* `underscore.js <https://underscorejs.org>`_
* `.NET Events <https://docs.microsoft.com/en-us/dotnet/standard/events>`_
Documentation
-------------
The complete `API documentation <https://eventkit.readthedocs.io/en/latest/api.html>`_.
.. _Python: http://www.python.org
.. _`Interactive Brokers Python API`: http://interactivebrokers.github.io
.. |Build| image:: https://github.com/ib-api-reloaded/eventkit/actions/workflows/build-n-test.yml/badge.svg
:alt: Build
:target: https://github.com/ib-api-reloaded/eventkit/actions
.. |PyPiVersion| image:: https://img.shields.io/pypi/v/aeventkit.svg
:alt: PyPi
:target: https://pypi.org/project/aeventkit/
.. |PyVersion| image:: https://img.shields.io/badge/python-3.11+-blue.svg
:alt:
.. |Status| image:: https://img.shields.io/badge/status-stable-green.svg
:alt:
.. |License| image:: https://img.shields.io/badge/license-BSD-blue.svg
:alt:
.. |Docs| image:: https://readthedocs.org/projects/eventkit/badge/?version=latest
:alt: Documentation
:target: https://eventkit.readthedocs.io
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 3.0.1 | 19 Oct 2026 | 1 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 20:58 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:ff3fc3ac7ec546d4e8f480b3297943688585834ac7d6bfb11600a0ed06e61efe