{"library":"pyro4","title":"Pyro4","description":"Pyro4 is a robust and mature distributed object middleware for Python, enabling remote method calls (RPC) between Python applications. It reached its last major release with 4.82 in August 2020 and is now in a maintenance-only mode, with active development having shifted to its successor, Pyro5. Pyro4 offers features like name server discovery, object exposure, and various serialization options, making it suitable for creating distributed systems, but users should be aware of its end-of-life status for new feature development.","language":"python","status":"maintenance","last_verified":"Mon May 18","install":{"commands":["pip install Pyro4"],"cli":{"name":"pyro4","version":"sh: 1: pyro4: not found"}},"imports":["from Pyro4 import Daemon","from Pyro4 import Proxy","from Pyro4 import expose","from Pyro4 import locateNS","from Pyro4 import URI","from Pyro4 import errors"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import Pyro4\nimport threading\nimport time\n\n# --- Server Code (run in a separate thread/process) ---\n@Pyro4.expose\nclass GreetingMaker(object):\n    def get_fortune(self, name):\n        return f\"Hello, {name}. This is your fortune from Pyro4!\"\n\ndef run_server():\n    # In a real scenario, you'd run 'pyro4-ns' in a separate terminal\n    # For this example, we mock the Name Server interaction locally.\n    # Or, you'd start the Name Server programmatically:\n    # ns_thread = threading.Thread(target=Pyro4.naming.startNsLoop, daemon=True)\n    # ns_thread.start()\n    # time.sleep(1) # Give it a moment to start\n    \n    print(\"Pyro4 server starting...\")\n    daemon = Pyro4.Daemon()\n    # We'll use a local registration for this quickstart without needing pyro4-ns to be separately run\n    # In a real app, you'd use ns = Pyro4.locateNS() and ns.register()\n    # For simplicity, we just register directly with the daemon and use its URI.\n    uri = daemon.register(GreetingMaker, \"example.greeting\")\n    print(f\"Object registered with URI: {uri}\")\n    print(\"Server ready. Waiting for calls...\")\n    daemon.requestLoop()\n\n# --- Client Code ---\ndef run_client(server_uri):\n    print(\"Pyro4 client connecting...\")\n    try:\n        # Use the URI obtained from the server directly\n        with Pyro4.Proxy(server_uri) as greeter:\n            print(\"Client got proxy.\")\n            print(greeter.get_fortune(\"World\"))\n            print(greeter.get_fortune(\"Pythonista\"))\n    except Exception as e:\n        print(f\"Client error: {e}\")\n\nif __name__ == \"__main__\":\n    # To make this runnable as a single script for quickstart:\n    # 1. Run the Name Server manually in a separate terminal: pyro4-ns\n    # 2. Then, run this script. The server will register itself.\n    # For this quickstart, we'll demonstrate a simplified local interaction\n    # without explicitly starting a separate Name Server process within the script.\n    # In a real distributed setup, `pyro4-ns` is essential.\n\n    # Simplified local setup: Server registers object, client connects directly to its URI\n    daemon = Pyro4.Daemon() # start a new Pyro daemon\n    server_uri = daemon.register(GreetingMaker, \"example.greeting\") # register the object\n    print(f\"Server object URI: {server_uri}\")\n\n    server_thread = threading.Thread(target=daemon.requestLoop, daemon=True)\n    server_thread.start()\n    time.sleep(0.5) # Give the server a moment to start\n\n    run_client(server_uri)\n\n    print(\"Demonstration complete.\")\n    daemon.shutdown()\n","lang":"python","description":"This quickstart demonstrates a basic Pyro4 remote procedure call (RPC). It shows a server exposing a `GreetingMaker` object and a client connecting to it to call a remote method. For a fully distributed setup, you would typically run `pyro4-ns` (the Pyro4 Name Server) in a separate terminal, and both server and client would interact with it via `Pyro4.locateNS()` for discovery. This example simplifies by sharing the URI directly for self-contained execution.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-18","installed_version":"4.82","pypi_latest":"4.82","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":1.6,"avg_import_s":0.1,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.08,"mem_mb":3.6,"disk_size":"18.5M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.06,"mem_mb":3.6,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.14,"mem_mb":4,"disk_size":"20.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.12,"mem_mb":4,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.1,"mem_mb":3.9,"disk_size":"12.4M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.11,"mem_mb":3.9,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.11,"mem_mb":4.7,"disk_size":"12.1M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"Pyro4","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":4.7,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.08,"mem_mb":3.7,"disk_size":"18.0M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"Pyro4","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.9,"import_time_s":0.08,"mem_mb":3.7,"disk_size":"19M"}]}}