{"id":19224279,"url":"https://github.com/aprowe/pyvent","last_synced_at":"2025-04-20T23:32:00.761Z","repository":{"id":40272361,"uuid":"174112817","full_name":"aprowe/pyvent","owner":"aprowe","description":"Easy Python IPC","archived":false,"fork":false,"pushed_at":"2022-05-17T06:10:32.000Z","size":18,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-01T07:04:05.230Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aprowe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-06T09:22:01.000Z","updated_at":"2024-02-20T18:27:11.000Z","dependencies_parsed_at":"2022-08-20T11:40:27.179Z","dependency_job_id":null,"html_url":"https://github.com/aprowe/pyvent","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aprowe%2Fpyvent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aprowe%2Fpyvent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aprowe%2Fpyvent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aprowe%2Fpyvent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aprowe","download_url":"https://codeload.github.com/aprowe/pyvent/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249977433,"owners_count":21354859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T15:11:11.207Z","updated_at":"2025-04-20T23:32:00.514Z","avatar_url":"https://github.com/aprowe.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pyvent\n\nPyvent is a dead-simple IPC to use that uses [ZMQ](https://pyzmq.readthedocs.io/en/latest/api/zmq.html) and [PyDispatcher](https://grass.osgeo.org/grass77/manuals/libpython/pydispatch.html) under the hood.\n\n### Concept\nFor python, ZMQ is one of the best options for a fast, easy IPC. The only problem is the relatively high amount of boilerplate code to get basic communication going between two processes. Pyvent is made to have all of\nthe benefits of a ZMQ IPC, with zero boiler plate code. The API uses a basic event emitter pattern, handling all threads and ZMQ behind the scenes. The ZMQ messages are basic enough that you could hook into the server from another language.\n\n## Installation\n```python\npip install pyvent\n```\n\nPyvent requires python 3.6 or higher\n\n## Usage\n\nPyvent employs a observer, event based pattern common in javascript and Qt. It uses PyDispatcher under the hood, and follows syntax as closely as possible to that.\n\n\n### Basic\n\n```python\n# script1.py\nimport pyvent\n\n@pyvent.connect('order-food')\ndef order(food, drink='water'):\n  print(f'You ordered {food} and {drink}!')\n```\n\n\n```python\n# script2.py\nimport pyvent\n\npyvent.send('order-food', food='sushi', drink='sake')\n```\n\n```shell\n$ python3 script1.py \u0026\n$ python3 script2.py\n\u003e You ordered sushi and sake!\n```\n\n### Features\n\n#### Connect as a decorator\nConnect can be called as a decorator or a normal function with a callback argument\n```python\nimport pyvent\n@pyvent.connect('food-burnt')\ndef fn():\n    print('Food is burnt :(')\n\n# Same as\npyvent.connect('food-burnt', fn)\n```\n\n#### Nodes\nCalling methods on the module are all proxy functions that call an underlying class called `Node`, which is the combination of a client and sometimes a server. For most use cases you can simply import `pyvent` and call it's module functions but for use in `multiprocessing` threads you likely need to manually start a node.\n\n```python\nimport pyvent\nfrom pyvent import Node\nfrom multiprocessing import Process\nfrom time import time\n\ndef process():\n    node = Node()\n\n    @node.connect('make-food')\n    def fn(food):\n        print(f'Making {food}')\n\n    time.sleep(1)\n\n# Create a process\np = Process(target=process)\np.start()\n\n# Create a node on this process\n# (Note that pyvent global functions would work too)\npyvent.send('make-food', food='chicken')\n\np.terminate()\n```\n\n#### Manually Starting Server\nYou may want more control over which process the server belongs to, and when it is started. Note that this happens on the first `send` or `connect` call\n```python\npyvent.start_server()\n```\n\n#### Blocking Listeners\n`pyvent.wait_for` is similar to connect, but will wait for a response and return the results. A timeout can be placed, and if it times out the response will be a tuple of `(None, None)`\n\n```python\nimport pyvent\n\nargs, kargs = pyvent.wait_for('food-ready', timeout=1)\n\nif kargs:\n    print(f'Food ready: {kargs[\"food\"]}')\nelse:\n    print('Took too long!')\n```\n\n#### Configuration\nThere are several options that can be configured. As of v0.1.1, these has to be entered before any other calls\n```python\nimport pyvent\n\npyvent.configure(\n    # Default port that communication will be on\n    # Note that as of v0.1.1 port and port + 1 will be used\n    port=50020,\n\n    # If False, the this process will not spawn a server\n    # Ff True, will only start up if needed\n    server=True,\n\n    # ID of this process for identifying its calls\n    id='pyvent'\n)\n\n# These options can also be entered into Node as construction arguments\nnode = pyvent.Node(server=False)\n```\n\n#### Stopping\nTo close all communication and halt threads, a `pyvent.stop()` call is needed. Upon deletion, `stop()` will be called.\nNote that as of v0.1.1 stopping is sometimes buggy and blocks\n\n#### Senders\nTo differentiate pyvent calls with other pydispatch calls, the default\nsender parameter on all connects and sends is 'pyvent'.\nIf a client has an id set, it's calls will be 'pyvent.{id}'.\nIf you call `send` or `connect` with a `sender` parameter, it will overwrite that. Note that due to traveling to another process,\ninstances can not be senders, only serializable objects.\n\n```python\nimport pyvent\nfrom pydispatch import dispatcher\n\n@pyvent.connect('new-customer', sender='customer-manager')\ndef fn(name):\n    print(f'A customer has arrived: {name}')\n\n# only sender='customer-manager.*' will trigger the vent\npyvent.send('new-customer', sender='customer-manager')\n\n# This will also trigger the event\ndispatcher.send(signal='new-customer', sender='customer-manager')\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faprowe%2Fpyvent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faprowe%2Fpyvent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faprowe%2Fpyvent/lists"}