Name | pymitter JSON |
Version |
1.1.3
JSON |
| download |
home_page | None |
Summary | Python port of the extended Node.js EventEmitter 2 approach providing namespaces, wildcards and TTL. |
upload_time | 2025-07-11 17:03:41 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.9 |
license | None |
keywords |
emitter
event
eventemitter
node
nodejs
wildcard
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
<!-- marker-before-logo -->
<p align="center">
<img src="https://media.githubusercontent.com/media/riga/pymitter/master/assets/logo.png" width="400" />
</p>
<!-- marker-after-logo -->
<!-- marker-before-badges -->
<p align="center">
<a href="http://pymitter.readthedocs.io">
<img alt="Documentation status" src="https://readthedocs.org/projects/pymitter/badge/?version=latest" />
</a>
<img alt="Python version" src="https://img.shields.io/badge/Python-%E2%89%A53.9-blue" />
<a href="https://pypi.python.org/pypi/pymitter">
<img alt="Package version" src="https://img.shields.io/pypi/v/pymitter.svg?style=flat" />
</a>
<a href="https://pypi.python.org/pypi/pymitter">
<img alt="Package downloads" src="https://img.shields.io/pypi/dm/pymitter.svg" />
</a>
<a href="https://codecov.io/gh/riga/pymitter">
<img alt="Code coverage" src="https://codecov.io/gh/riga/pymitter/branch/master/graph/badge.svg?token=MePbStZF7U" />
</a>
<a href="https://github.com/riga/pymitter/actions/workflows/lint_and_test.yml">
<img alt="Build status" src="https://github.com/riga/pymitter/actions/workflows/lint_and_test.yml/badge.svg" />
</a>
<a href="https://github.com/riga/pymitter/blob/master/LICENSE">
<img alt="License" src="https://img.shields.io/github/license/riga/pymitter.svg" />
</a>
</p>
<!-- marker-after-badges -->
<!-- marker-before-header -->
Python port of the extended Node.js EventEmitter 2 approach of https://github.com/asyncly/EventEmitter2 providing namespaces, wildcards and TTL.
Original source hosted at [GitHub](https://github.com/riga/pymitter).
<!-- marker-after-header -->
<!-- marker-before-body -->
## Features
- Namespaces with wildcards
- Times to listen (TTL)
- Usage via decorators or callbacks
- Coroutine support
- Lightweight implementation, good performance
## Installation
Simply install via [pip](https://pypi.python.org/pypi/pymitter):
```shell
pip install pymitter
```
- The last version supporting Python 2 was [v0.3.2](https://github.com/riga/pymitter/tree/v0.3.2) ([PyPI](https://pypi.org/project/pymitter/0.3.2)).
- The last version supporting Python ≤3.8 was [v1.0.0](https://github.com/riga/pymitter/tree/v1.0.0) ([PyPI](https://pypi.org/project/pymitter/1.0.0)).
## Examples
### Basic usage
```python
from pymitter import EventEmitter
ee = EventEmitter()
# decorator usage
@ee.on("my_event")
def handler1(arg):
print("handler1 called with", arg)
# callback usage
def handler2(arg):
print("handler2 called with", arg)
ee.on("my_other_event", handler2)
# support for coroutine functions
@ee.on("my_third_event")
async def handler3(arg):
print("handler3 called with", arg)
# emit
ee.emit("my_event", "foo")
# -> "handler1 called with foo"
ee.emit("my_other_event", "bar")
# -> "handler2 called with bar"
ee.emit("my_third_event", "baz")
# -> "handler3 called with baz"
```
### Coroutines
Wrapping `async` functions outside an event loop will start an internal event loop and calls to `emit` return synchronously.
```python
from pymitter import EventEmitter
ee = EventEmitter()
# register an async function
@ee.on("my_event")
async def handler1(arg):
print("handler1 called with", arg)
# emit
ee.emit("my_event", "foo")
# -> "handler1 called with foo"
```
Wrapping `async` functions inside an event loop will use the same loop and `emit_async` is awaitable.
```python
from pymitter import EventEmitter
ee = EventEmitter()
async def main():
# emit_async
awaitable = ee.emit_async("my_event", "foo")
# -> nothing printed yet
await awaitable
# -> "handler1 called with foo"
```
Use `emit_future` to not return awaitable objects but to place them at the end of the existing event loop (using `asyncio.ensure_future` internally).
### TTL (times to listen)
```python
from pymitter import EventEmitter
ee = EventEmitter()
@ee.once("my_event")
def handler1():
print("handler1 called")
@ee.on("my_event", ttl=2)
def handler2():
print("handler2 called")
ee.emit("my_event")
# -> "handler1 called"
# -> "handler2 called"
ee.emit("my_event")
# -> "handler2 called"
ee.emit("my_event")
# nothing called anymore
```
### Wildcards
```python
from pymitter import EventEmitter
ee = EventEmitter(wildcard=True)
@ee.on("my_event.foo")
def handler1():
print("handler1 called")
@ee.on("my_event.bar")
def handler2():
print("handler2 called")
@ee.on("my_event.*")
def hander3():
print("handler3 called")
ee.emit("my_event.foo")
# -> "handler1 called"
# -> "handler3 called"
ee.emit("my_event.bar")
# -> "handler2 called"
# -> "handler3 called"
ee.emit("my_event.*")
# -> "handler1 called"
# -> "handler2 called"
# -> "handler3 called"
```
## API
### `EventEmitter(*, wildcard=False, delimiter=".", new_listener=False, max_listeners=-1)`
EventEmitter constructor. **Note**: always use *kwargs* for configuration.
When *wildcard* is *True*, wildcards are used as shown in [this example](#wildcards).
*delimiter* is used to separate namespaces within events.
If *new_listener* is *True*, the *"new_listener"* event is emitted every time a new listener is registered.
Functions listening to this event are passed `(func, event=None)`.
*max_listeners* defines the maximum number of listeners per event.
Negative values mean infinity.
- #### `on(event, func=None, ttl=-1)`
Registers a function to an event.
When *func* is *None*, decorator usage is assumed.
*ttl* defines the times to listen. Negative values mean infinity.
Returns the function.
- #### `once(event, func=None)`
Registers a function to an event with `ttl = 1`.
When *func* is *None*, decorator usage is assumed.
Returns the function.
- #### `on_any(func=None)`
Registers a function that is called every time an event is emitted.
When *func* is *None*, decorator usage is assumed.
Returns the function.
- #### `off(event, func=None)`
Removes a function that is registered to an event and returns it.
When *func* is *None*, all functions of *event* are removed and *None* is returned.
- #### `off_any(func=None)`
Removes a function that was registered via `on_any()`.
When *func* is *None*, decorator usage is assumed.
Returns the function.
- #### `off_all()`
Removes all functions of all events.
- #### `listeners(event)`
Returns all functions that are registered to an event.
Wildcards are not applied.
- #### `listeners_any()`
Returns all functions that were registered using `on_any()`.
- #### `listeners_all()`
Returns all registered functions.
- #### `emit(event, *args, **kwargs)`
Emits an event.
All functions of events that match *event* are invoked with *args* and *kwargs* in the exact order of their registration.
Async functions are called in a new event loop.
There is no return value.
- #### `(async) emit_async(event, *args, **kwargs)`
Emits an event.
All functions of events that match *event* are invoked with *args* and *kwargs* in the exact order of their registration.
Awaitable objects returned by async functions are awaited in the outer event loop.
Returns an `Awaitable`.
- #### `emit_future(event, *args, **kwargs)`
Emits an event.
All functions of events that match *event* are invoked with *args* and *kwargs* in the exact order of their registration.
Awaitable objects returned by async functions are placed at the end of the event loop using `asyncio.ensure_future`.
There is no return value.
## Development
- Source hosted at [GitHub](https://github.com/riga/pymitter)
- Python module hosted at [PyPI](https://pypi.python.org/pypi/pymitter)
- Report issues, questions, feature requests on [GitHub Issues](https://github.com/riga/pymitter/issues)
<!-- marker-after-body -->
Raw data
{
"_id": null,
"home_page": null,
"name": "pymitter",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "emitter, event, eventemitter, node, nodejs, wildcard",
"author": null,
"author_email": "Marcel Rieger <github.riga@icloud.com>",
"download_url": "https://files.pythonhosted.org/packages/7a/d6/87fa9e93640938fe1836a12157eac2ab36299ff1549dae30a677bf764789/pymitter-1.1.3.tar.gz",
"platform": null,
"description": "<!-- marker-before-logo -->\n\n<p align=\"center\">\n <img src=\"https://media.githubusercontent.com/media/riga/pymitter/master/assets/logo.png\" width=\"400\" />\n</p>\n\n<!-- marker-after-logo -->\n\n<!-- marker-before-badges -->\n\n<p align=\"center\">\n <a href=\"http://pymitter.readthedocs.io\">\n <img alt=\"Documentation status\" src=\"https://readthedocs.org/projects/pymitter/badge/?version=latest\" />\n </a>\n <img alt=\"Python version\" src=\"https://img.shields.io/badge/Python-%E2%89%A53.9-blue\" />\n <a href=\"https://pypi.python.org/pypi/pymitter\">\n <img alt=\"Package version\" src=\"https://img.shields.io/pypi/v/pymitter.svg?style=flat\" />\n </a>\n <a href=\"https://pypi.python.org/pypi/pymitter\">\n <img alt=\"Package downloads\" src=\"https://img.shields.io/pypi/dm/pymitter.svg\" />\n </a>\n <a href=\"https://codecov.io/gh/riga/pymitter\">\n <img alt=\"Code coverage\" src=\"https://codecov.io/gh/riga/pymitter/branch/master/graph/badge.svg?token=MePbStZF7U\" />\n </a>\n <a href=\"https://github.com/riga/pymitter/actions/workflows/lint_and_test.yml\">\n <img alt=\"Build status\" src=\"https://github.com/riga/pymitter/actions/workflows/lint_and_test.yml/badge.svg\" />\n </a>\n <a href=\"https://github.com/riga/pymitter/blob/master/LICENSE\">\n <img alt=\"License\" src=\"https://img.shields.io/github/license/riga/pymitter.svg\" />\n </a>\n</p>\n\n<!-- marker-after-badges -->\n\n<!-- marker-before-header -->\n\nPython port of the extended Node.js EventEmitter 2 approach of https://github.com/asyncly/EventEmitter2 providing namespaces, wildcards and TTL.\n\nOriginal source hosted at [GitHub](https://github.com/riga/pymitter).\n\n<!-- marker-after-header -->\n\n<!-- marker-before-body -->\n\n## Features\n\n- Namespaces with wildcards\n- Times to listen (TTL)\n- Usage via decorators or callbacks\n- Coroutine support\n- Lightweight implementation, good performance\n\n## Installation\n\nSimply install via [pip](https://pypi.python.org/pypi/pymitter):\n\n```shell\npip install pymitter\n```\n\n- The last version supporting Python 2 was [v0.3.2](https://github.com/riga/pymitter/tree/v0.3.2) ([PyPI](https://pypi.org/project/pymitter/0.3.2)).\n- The last version supporting Python \u22643.8 was [v1.0.0](https://github.com/riga/pymitter/tree/v1.0.0) ([PyPI](https://pypi.org/project/pymitter/1.0.0)).\n\n## Examples\n\n### Basic usage\n\n```python\nfrom pymitter import EventEmitter\n\n\nee = EventEmitter()\n\n\n# decorator usage\n@ee.on(\"my_event\")\ndef handler1(arg):\n print(\"handler1 called with\", arg)\n\n\n# callback usage\ndef handler2(arg):\n print(\"handler2 called with\", arg)\n\n\nee.on(\"my_other_event\", handler2)\n\n\n# support for coroutine functions\n@ee.on(\"my_third_event\")\nasync def handler3(arg):\n print(\"handler3 called with\", arg)\n\n\n# emit\nee.emit(\"my_event\", \"foo\")\n# -> \"handler1 called with foo\"\n\nee.emit(\"my_other_event\", \"bar\")\n# -> \"handler2 called with bar\"\n\nee.emit(\"my_third_event\", \"baz\")\n# -> \"handler3 called with baz\"\n```\n\n### Coroutines\n\nWrapping `async` functions outside an event loop will start an internal event loop and calls to `emit` return synchronously.\n\n```python\nfrom pymitter import EventEmitter\n\n\nee = EventEmitter()\n\n\n# register an async function\n@ee.on(\"my_event\")\nasync def handler1(arg):\n print(\"handler1 called with\", arg)\n\n\n# emit\nee.emit(\"my_event\", \"foo\")\n# -> \"handler1 called with foo\"\n```\n\nWrapping `async` functions inside an event loop will use the same loop and `emit_async` is awaitable.\n\n```python\nfrom pymitter import EventEmitter\n\n\nee = EventEmitter()\n\n\nasync def main():\n # emit_async\n awaitable = ee.emit_async(\"my_event\", \"foo\")\n # -> nothing printed yet\n\n await awaitable\n # -> \"handler1 called with foo\"\n```\n\nUse `emit_future` to not return awaitable objects but to place them at the end of the existing event loop (using `asyncio.ensure_future` internally).\n\n### TTL (times to listen)\n\n```python\nfrom pymitter import EventEmitter\n\n\nee = EventEmitter()\n\n\n@ee.once(\"my_event\")\ndef handler1():\n print(\"handler1 called\")\n\n\n@ee.on(\"my_event\", ttl=2)\ndef handler2():\n print(\"handler2 called\")\n\n\nee.emit(\"my_event\")\n# -> \"handler1 called\"\n# -> \"handler2 called\"\n\nee.emit(\"my_event\")\n# -> \"handler2 called\"\n\nee.emit(\"my_event\")\n# nothing called anymore\n```\n\n### Wildcards\n\n```python\nfrom pymitter import EventEmitter\n\n\nee = EventEmitter(wildcard=True)\n\n\n@ee.on(\"my_event.foo\")\ndef handler1():\n print(\"handler1 called\")\n\n\n@ee.on(\"my_event.bar\")\ndef handler2():\n print(\"handler2 called\")\n\n\n@ee.on(\"my_event.*\")\ndef hander3():\n print(\"handler3 called\")\n\n\nee.emit(\"my_event.foo\")\n# -> \"handler1 called\"\n# -> \"handler3 called\"\n\nee.emit(\"my_event.bar\")\n# -> \"handler2 called\"\n# -> \"handler3 called\"\n\nee.emit(\"my_event.*\")\n# -> \"handler1 called\"\n# -> \"handler2 called\"\n# -> \"handler3 called\"\n```\n\n## API\n\n### `EventEmitter(*, wildcard=False, delimiter=\".\", new_listener=False, max_listeners=-1)`\n\nEventEmitter constructor. **Note**: always use *kwargs* for configuration.\nWhen *wildcard* is *True*, wildcards are used as shown in [this example](#wildcards).\n*delimiter* is used to separate namespaces within events.\nIf *new_listener* is *True*, the *\"new_listener\"* event is emitted every time a new listener is registered.\nFunctions listening to this event are passed `(func, event=None)`.\n*max_listeners* defines the maximum number of listeners per event.\nNegative values mean infinity.\n\n- #### `on(event, func=None, ttl=-1)`\n Registers a function to an event.\n When *func* is *None*, decorator usage is assumed.\n *ttl* defines the times to listen. Negative values mean infinity.\n Returns the function.\n\n- #### `once(event, func=None)`\n Registers a function to an event with `ttl = 1`.\n When *func* is *None*, decorator usage is assumed.\n Returns the function.\n\n- #### `on_any(func=None)`\n Registers a function that is called every time an event is emitted.\n When *func* is *None*, decorator usage is assumed.\n Returns the function.\n\n- #### `off(event, func=None)`\n Removes a function that is registered to an event and returns it.\n When *func* is *None*, all functions of *event* are removed and *None* is returned.\n\n- #### `off_any(func=None)`\n Removes a function that was registered via `on_any()`.\n When *func* is *None*, decorator usage is assumed.\n Returns the function.\n\n- #### `off_all()`\n Removes all functions of all events.\n\n- #### `listeners(event)`\n Returns all functions that are registered to an event.\n Wildcards are not applied.\n\n- #### `listeners_any()`\n Returns all functions that were registered using `on_any()`.\n\n- #### `listeners_all()`\n Returns all registered functions.\n\n- #### `emit(event, *args, **kwargs)`\n Emits an event.\n All functions of events that match *event* are invoked with *args* and *kwargs* in the exact order of their registration.\n Async functions are called in a new event loop.\n There is no return value.\n\n- #### `(async) emit_async(event, *args, **kwargs)`\n Emits an event.\n All functions of events that match *event* are invoked with *args* and *kwargs* in the exact order of their registration.\n Awaitable objects returned by async functions are awaited in the outer event loop.\n Returns an `Awaitable`.\n\n- #### `emit_future(event, *args, **kwargs)`\n Emits an event.\n All functions of events that match *event* are invoked with *args* and *kwargs* in the exact order of their registration.\n Awaitable objects returned by async functions are placed at the end of the event loop using `asyncio.ensure_future`.\n There is no return value.\n\n## Development\n\n- Source hosted at [GitHub](https://github.com/riga/pymitter)\n- Python module hosted at [PyPI](https://pypi.python.org/pypi/pymitter)\n- Report issues, questions, feature requests on [GitHub Issues](https://github.com/riga/pymitter/issues)\n\n<!-- marker-after-body -->\n",
"bugtrack_url": null,
"license": null,
"summary": "Python port of the extended Node.js EventEmitter 2 approach providing namespaces, wildcards and TTL.",
"version": "1.1.3",
"project_urls": {
"Bug Tracker": "https://github.com/riga/pymitter/issues",
"Changelog": "https://github.com/riga/pymitter/releases",
"Documentation": "https://pymitter.readthedocs.io",
"Homepage": "https://github.com/riga/pymitter",
"Repository": "https://github.com/riga/pymitter.git"
},
"split_keywords": [
"emitter",
" event",
" eventemitter",
" node",
" nodejs",
" wildcard"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "b19d34257252be022b7e776794e9ee30abc88322adb70e3cbb15bdfd44afe88d",
"md5": "f40cd83e34affa01f708e34c3d6b741c",
"sha256": "7e7644af9393f06b446c55c33ea5e4f31d0e2557971339a971f736467201f901"
},
"downloads": -1,
"filename": "pymitter-1.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f40cd83e34affa01f708e34c3d6b741c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 8513,
"upload_time": "2025-07-11T17:03:39",
"upload_time_iso_8601": "2025-07-11T17:03:39.711662Z",
"url": "https://files.pythonhosted.org/packages/b1/9d/34257252be022b7e776794e9ee30abc88322adb70e3cbb15bdfd44afe88d/pymitter-1.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7ad687fa9e93640938fe1836a12157eac2ab36299ff1549dae30a677bf764789",
"md5": "8bb72b3d064e682cdcac654d71205fc9",
"sha256": "8f29abbaf1f2152b27dd092c7d2e557e06bcd0c7a560105689fd889e0c3d944d"
},
"downloads": -1,
"filename": "pymitter-1.1.3.tar.gz",
"has_sig": false,
"md5_digest": "8bb72b3d064e682cdcac654d71205fc9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 14716,
"upload_time": "2025-07-11T17:03:41",
"upload_time_iso_8601": "2025-07-11T17:03:41.732361Z",
"url": "https://files.pythonhosted.org/packages/7a/d6/87fa9e93640938fe1836a12157eac2ab36299ff1549dae30a677bf764789/pymitter-1.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-11 17:03:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "riga",
"github_project": "pymitter",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pymitter"
}