Catalog PyPI
PACKAGE EXPLORERView in registry

aeventkit

PyPI

Event-driven data pipelines

asynciodatadriveneventpipelinespython
Versions collected1
Direct dependencies1From release 3.0.1
Last observed20 Oct, 20:58 UTC

README

Version 3.0.1 documentation
|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

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
3.0.119 Oct 20261

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
ib-api-reloaded/eventkit

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 20:58 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:ff3fc3ac7ec546d4e8f480b3297943688585834ac7d6bfb11600a0ed06e61efe