{"library":"pyro5","title":"Pyro5 Remote Object Communication Library","description":"Pyro5 is a Python library for remote object communication, enabling client-server interactions across different processes or machines. It's the fifth major version of the Pyro project, emphasizing ease of use and flexibility. As of version 5.16, the project has entered a low maintenance mode, with active development paused unless critical bugs are reported.","language":"python","status":"maintenance","last_verified":"Mon May 18","install":{"commands":["pip install pyro5"],"cli":null},"imports":["from Pyro5.api import Daemon","from Pyro5.api import expose","from Pyro5.api import locate_ns","from Pyro5.api import Proxy","from Pyro5.api import URI","from Pyro5.api import Daemon"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import Pyro5.api\nimport time\nimport threading\n\n# --- Server side (run in one terminal) ---\n@Pyro5.api.expose\nclass MyServer:\n    def greet(self, name):\n        return f\"Hello, {name}! This is Pyro5.\"\n\n    def echo(self, message):\n        return f\"Server received: {message}\"\n\n    def get_time(self):\n        return time.time()\n\ndef run_server():\n    # Start a Name Server in a separate terminal: python -m Pyro5.nameserver\n    # Or, start one programmatically if not using a shared nameserver\n    # For simplicity, we'll try to connect to one assumed to be running on localhost\n    try:\n        ns = Pyro5.api.locate_ns(host=\"localhost\")\n    except Pyro5.errors.NamingError:\n        print(\"No Name Server found. Please start one: python -m Pyro5.nameserver\")\n        return\n\n    daemon = Pyro5.api.Daemon(host=\"localhost\")\n    uri = daemon.register(MyServer, \"example.myserver\") # Register with a name\n    ns.register(\"example.myserver\", uri) # Register the URI with the Name Server\n    print(f\"Server URI: {uri}\")\n    print(\"Server ready. Object registered as 'example.myserver'.\")\n    print(\"Starting event loop (Ctrl+C to stop)...\")\n    daemon.requestLoop()\n\n# --- Client side (run in another terminal) ---\ndef run_client():\n    # Locate the Name Server to find the object\n    try:\n        ns = Pyro5.api.locate_ns(host=\"localhost\")\n    except Pyro5.errors.NamingError:\n        print(\"No Name Server found. Cannot connect to server.\")\n        return\n\n    uri = ns.lookup(\"example.myserver\") # Look up the object's URI by its name\n\n    # Create a proxy to the remote object\n    with Pyro5.api.Proxy(uri) as server_proxy:\n        print(f\"Greeting: {server_proxy.greet('Pyro User')}\")\n        print(f\"Echo: {server_proxy.echo('This is a test message.')}\")\n        print(f\"Remote time: {server_proxy.get_time()}\")\n\nif __name__ == '__main__':\n    # This quickstart demonstrates client-server. \n    # For actual usage, run server and client in separate processes.\n    print(\"--- Pyro5 Quickstart ---\")\n    print(\"To run, first start the Pyro Name Server in a *separate* terminal:\")\n    print(\"  python -m Pyro5.nameserver\n\")\n    print(\"Then run this script. It will run the server, wait, then the client.\")\n    print(\"Or, copy the server part to 'server.py' and client to 'client.py' and run them separately.\")\n\n    # Simplified running for quickstart; normally they are separate processes\n    server_thread = threading.Thread(target=run_server)\n    server_thread.daemon = True # Allow main program to exit even if server is running\n    server_thread.start()\n\n    print(\"\\nWaiting for server to start and register...\")\n    time.sleep(2) # Give server a moment to start and register\n\n    print(\"\\n--- Running Client ---\")\n    run_client()\n    print(\"\\nClient finished.\")\n    # The server thread will continue running until Ctrl+C if it was main, \n    # but here it's a daemon thread so it will exit with main.\n","lang":"python","description":"This quickstart demonstrates a basic Pyro5 client-server interaction. It defines a server class, registers it with a Pyro Name Server, and then a client looks up the server and calls its methods. \n\nBefore running, ensure you start the Pyro Name Server in a *separate* terminal using `python -m Pyro5.nameserver`. This is crucial for name lookup. \n\nThe provided code attempts to run both server and client within the same script using threads for convenience, but in typical usage, they are separate processes, potentially on different machines.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-18","installed_version":"5.16","pypi_latest":"5.16","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":1.6,"avg_import_s":0.12,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.1,"mem_mb":4.3,"disk_size":"18.4M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.07,"mem_mb":4.3,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.18,"mem_mb":4.8,"disk_size":"20.4M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.7,"import_time_s":0.14,"mem_mb":4.8,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.13,"mem_mb":4.7,"disk_size":"12.3M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.15,"mem_mb":4.7,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.13,"mem_mb":5.2,"disk_size":"12.0M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.12,"mem_mb":5.2,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.09,"mem_mb":4.2,"disk_size":"17.9M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pyro5","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.8,"import_time_s":0.08,"mem_mb":4.2,"disk_size":"18M"}]}}