{"id":19973225,"url":"https://github.com/zeromq/pyre","last_synced_at":"2025-05-16T08:04:14.825Z","repository":{"id":11427588,"uuid":"13880433","full_name":"zeromq/pyre","owner":"zeromq","description":"Python port of Zyre","archived":false,"fork":false,"pushed_at":"2025-01-13T10:54:24.000Z","size":385,"stargazers_count":123,"open_issues_count":23,"forks_count":51,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-04-12T04:49:10.074Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zeromq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-10-26T08:45:49.000Z","updated_at":"2025-01-13T10:54:28.000Z","dependencies_parsed_at":"2025-01-16T01:08:09.681Z","dependency_job_id":"c41435bd-097d-4d16-8f46-88e822eaf47b","html_url":"https://github.com/zeromq/pyre","commit_stats":{"total_commits":285,"total_committers":28,"mean_commits":"10.178571428571429","dds":0.5789473684210527,"last_synced_commit":"de0e9014e43458191828aafdd050f2080b6804ad"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeromq%2Fpyre","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeromq%2Fpyre/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeromq%2Fpyre/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeromq%2Fpyre/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zeromq","download_url":"https://codeload.github.com/zeromq/pyre/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253891785,"owners_count":21979856,"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-13T03:10:41.842Z","updated_at":"2025-05-16T08:04:09.817Z","avatar_url":"https://github.com/zeromq.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Pyre\n====\n\nThis is a Python port of [Zyre](http://zyre.org) 1.0, implementing the same [ZRE protocol](http://rfc.zeromq.org/spec:36).\n\n# Pyre - an open-source framework for proximity-based peer-to-peer applications\n\n## Description\n\nPyre does local area discovery and clustering. A Pyre node broadcasts\nUDP beacons, and connects to peers that it finds. This class wraps a\nPyre node with a message-based API.\n\nAll incoming events are messages delivered via the recv call of a Pyre\ninstance. The first frame defines the type of the message, and following\nframes provide further values:\n\n    ENTER fromnode headers\n        a new peer has entered the network\n    EXIT fromnode\n        a peer has left the network\n    JOIN fromnode groupname\n        a peer has joined a specific group\n    LEAVE fromnode groupname\n        a peer has joined a specific group\n    WHISPER fromnode message\n        a peer has sent this node a message\n    SHOUT fromnode groupname message\n        a peer has sent one of our groups a message\n\nIn SHOUT and WHISPER the message is a single frame in this version\nof Pyre. In ENTER, the headers frame contains a packed dictionary, \nthat can be unpacked using json.loads(msg) (see chat client).\n\nTo join or leave a group, use the join() and leave() methods.\nTo set a header value, use the set_header() method. To send a message\nto a single peer, use whisper(). To send a message to a group, use\nshout().\n\n## Installation\n\nFor now use Pip:\n\n    pip install https://github.com/zeromq/pyre/archive/master.zip\n\n## API\n\n    import pyre\n    #  Constructor, creates a new Zyre node. Note that until you start the\n    #  node it is silent and invisible to other nodes on the network.\n    node = pyre.Pyre()\n\n    #  Set node header; these are provided to other nodes during discovery\n    #  and come in each ENTER message.\n    node.set_header(name, value)\n\n    #  (TODO: Currently a Pyre node starts immediately) Start node, after setting header values. When you start a node it\n    #  begins discovery and connection.\n    node.start()\n\n    #  Stop node, this signals to other peers that this node will go away.\n    #  This is polite; however you can also just destroy the node without\n    #  stopping it.\n    node.stop()\n\n    #  Join a named group; after joining a group you can send messages to\n    #  the group and all Zyre nodes in that group will receive them.\n    node.join(group)\n\n    #  Leave a group\n    node.leave(group)\n\n    #  Receive next message from network; the message may be a control\n    #  message (ENTER, EXIT, JOIN, LEAVE) or data (WHISPER, SHOUT).\n    #  Returns a list of message frames\n    msgs = node.recv();\n\n    # Send message to single peer, specified as a UUID object (import uuid)\n    # Destroys message after sending\n    node.whisper(peer, msg)\n\n    # Send message to a named group\n    # Destroys message after sending\n    node.shout(group, msg);\n\n    #  Send string to single peer specified as a UUID string.\n    #  String is formatted using printf specifiers.\n    node.whispers(peer, msg_string)\n\n    #  Send message to a named group\n    #  Destroys message after sending\n    node.shouts(group, msg_string);\n        \n    #  Return handle to the Zyre node, for polling\n    node.get_socket()\n    # use node.get_socket().getsockopt(zmq.FD) to acquire \n    # the filedescriptor\n    # Don't use this for getting Pyre events you can use the \n    # node.inbox to get those events\n\n## Example Chat Client\n\n```python\ntry:\n    from zyre_pyzmq import Zyre as Pyre\nexcept Exception as e:\n    print(\"using Python native module\", e)\n    from pyre import Pyre \n\nfrom pyre import zhelper \nimport zmq \nimport uuid\nimport logging\nimport sys\nimport json\n\ndef chat_task(ctx, pipe):\n    n = Pyre(\"CHAT\")\n    n.set_header(\"CHAT_Header1\",\"example header1\")\n    n.set_header(\"CHAT_Header2\",\"example header2\")\n    n.join(\"CHAT\")\n    n.start()\n\n    poller = zmq.Poller()\n    poller.register(pipe, zmq.POLLIN)\n    print(n.socket())\n    poller.register(n.socket(), zmq.POLLIN)\n    print(n.socket())\n    while(True):\n        items = dict(poller.poll())\n        print(n.socket(), items)\n        if pipe in items and items[pipe] == zmq.POLLIN:\n            message = pipe.recv()\n            # message to quit\n            if message.decode('utf-8') == \"$$STOP\":\n                break\n            print(\"CHAT_TASK: %s\" % message)\n            n.shouts(\"CHAT\", message.decode('utf-8'))\n        else:\n        #if n.socket() in items and items[n.socket()] == zmq.POLLIN:\n            cmds = n.recv()\n            msg_type = cmds.pop(0)\n            print(\"NODE_MSG TYPE: %s\" % msg_type)\n            print(\"NODE_MSG PEER: %s\" % uuid.UUID(bytes=cmds.pop(0)))\n            print(\"NODE_MSG NAME: %s\" % cmds.pop(0))\n            if msg_type.decode('utf-8') == \"SHOUT\":\n                print(\"NODE_MSG GROUP: %s\" % cmds.pop(0))\n            elif msg_type.decode('utf-8') == \"ENTER\":\n                headers = json.loads(cmds.pop(0).decode('utf-8'))\n                print(\"NODE_MSG HEADERS: %s\" % headers)\n                for key in headers:\n                    print(\"key = {0}, value = {1}\".format(key, headers[key]))\n            print(\"NODE_MSG CONT: %s\" % cmds)\n    n.stop()\n\n\nif __name__ == '__main__':\n    # Create a StreamHandler for debugging\n    logger = logging.getLogger(\"pyre\")\n    logger.setLevel(logging.INFO)\n    logger.addHandler(logging.StreamHandler())\n    logger.propagate = False\n\n    ctx = zmq.Context()\n    chat_pipe = zhelper.zthread_fork(ctx, chat_task)\n    # input in python 2 is different\n    if sys.version_info.major \u003c 3:\n        input = raw_input\n\n    while True:\n        try:\n            msg = input()\n            chat_pipe.send(msg.encode('utf_8'))\n        except (KeyboardInterrupt, SystemExit):\n            break\n    chat_pipe.send(\"$$STOP\".encode('utf_8'))\n    print(\"FINISHED\")\n```\n\nLook at the [ZOCP](https://github.com/z25/pyZOCP) project for examples of how Pyre can be \nintegrated into different environments and frameworks, i.e.:\n- [Urwid](https://github.com/z25/pyZOCP/blob/master/examples/urwZOCP.py)\n- [Blender](https://github.com/z25/pyZOCP/blob/master/examples/BpyZOCP.py)\n- [Glib](https://github.com/z25/pyZOCP/blob/master/examples/glib_node.py)\n- [QT](https://github.com/z25/pyZOCP/blob/master/examples/qt_ui_node.py)\n\n\nPyre uses the [Python Logging](https://docs.python.org/3.4/library/logging.html) module.\nTo change the debug level:\n\n```\n    # Create a StreamHandler for debugging\n    logger = logging.getLogger(\"pyre\")\n    logger.setLevel(logging.INFO)\n    # i.e. logging.DEBUG, logging.WARNING\n    logger.addHandler(logging.StreamHandler())\n    logger.propagate = False\n\n```\n\n## Requirements\n\nPython only needs PyZMQ. On some older versions of Python \nit also needs the [ipaddress](https://docs.python.org/3.4/library/ipaddress.html?highlight=ipaddress#module-ipaddress) module.\n\nThe recommended Python version is 3.3+\n\n\n## Project Organization\n\nPyre is owned by all its authors and contributors. This is an open source\nproject licensed under the LGPLv3. To contribute to Zyre please read the\n[C4.1 process](http://rfc.zeromq.org/spec:22) that we use.\n\nTo report an issue, use the [PYRE issue tracker](https://github.com/zeromq/pyre/issues) at github.com.\n\nFor more information on this project's maintenance, see [`MAINTENANCE.md`](MAINTENANCE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeromq%2Fpyre","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzeromq%2Fpyre","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeromq%2Fpyre/lists"}