{"id":7325,"library":"json-rpc","title":"JSON-RPC","description":"The `json-rpc` library provides a Python implementation of the JSON-RPC 2.0 protocol, offering tools for both server-side request dispatching and client-side request construction. It focuses on the protocol messaging rather than the underlying transport. The current version is 1.15.0, and it maintains a stable release cadence primarily addressing bug fixes and minor enhancements.","status":"active","version":"1.15.0","language":"en","source_language":"en","source_url":"https://github.com/pavlov99/json-rpc","tags":["json-rpc","rpc","protocol","serialization"],"install":[{"cmd":"pip install json-rpc","lang":"bash","label":"Install `json-rpc`"},{"cmd":"pip install json-rpc werkzeug","lang":"bash","label":"Install with common HTTP server dependencies"}],"dependencies":[{"reason":"Python 2/3 compatibility layer (often a transitive dependency, may not be strictly necessary for Python 3.7+)","package":"six","optional":false},{"reason":"Commonly used for building HTTP/WSGI-based JSON-RPC servers, but not strictly required for the core protocol logic.","package":"werkzeug","optional":true}],"imports":[{"symbol":"JSONRPCResponseManager","correct":"from jsonrpc.manager import JSONRPCResponseManager"},{"symbol":"JSONRPCClient","correct":"from jsonrpc.client import JSONRPCClient"},{"note":"The package is installed as `json-rpc` but imported as `jsonrpc`.","wrong":"import json_rpc","symbol":"jsonrpc","correct":"import jsonrpc"}],"quickstart":{"code":"import json\nimport os\nfrom jsonrpc.manager import JSONRPCResponseManager\nfrom jsonrpc.client import JSONRPCClient\n\n# --- Server-side logic (how to handle an incoming JSON-RPC request) ---\n\ndef add(a, b):\n    return a + b\n\ndef greet(name=\"Guest\"):\n    return f\"Hello, {name}!\"\n\ndef secure_data(token):\n    # Simulate an authentication check using an environment variable\n    expected_token = os.environ.get('AUTH_TOKEN', 'super_secret_token_123')\n    if token == expected_token:\n        return \"Sensitive data accessed.\"\n    else:\n        # JSON-RPC error response is automatically handled by the manager\n        raise ValueError(\"Invalid token\")\n\n# Define a dispatcher mapping method names to Python functions\ndispatcher = {\n    \"add\": add,\n    \"greet\": greet,\n    \"secure_data\": secure_data,\n}\n\n# Simulate an incoming raw JSON-RPC request string\nincoming_request_str = json.dumps({\n    \"jsonrpc\": \"2.0\",\n    \"method\": \"add\",\n    \"params\": {\"a\": 5, \"b\": 3},\n    \"id\": \"req-123\"\n})\n\n# Process the request using the manager\nprint(\"--- Server processing request ---\")\nresponse_object = JSONRPCResponseManager.handle(incoming_request_str, dispatcher)\n\nif response_object:\n    # `response_object.json` contains the Python dict representation of the JSON-RPC response\n    print(json.dumps(response_object.json, indent=2))\nelse:\n    print(\"No response object (e.g., for a notification without 'id').\")\n\n# Simulate a request with authentication failure\nprint(\"\\n--- Server processing authenticated request with wrong token ---\")\nauth_request_str = json.dumps({\n    \"jsonrpc\": \"2.0\",\n    \"method\": \"secure_data\",\n    \"params\": [\"wrong_token\"],\n    \"id\": \"auth-req-456\"\n})\nauth_response_object = JSONRPCResponseManager.handle(auth_request_str, dispatcher)\nif auth_response_object:\n    print(json.dumps(auth_response_object.json, indent=2))\n\n# --- Client-side logic (how to construct a JSON-RPC request) ---\n\n# JSONRPCClient helps in constructing the request payload.\n# It does NOT handle the actual network transport (e.g., HTTP POST).\n# You would typically subclass it or use its .call() method to get the payload,\n# then use a library like 'requests' to send it.\n\nclass MyDummyTransportClient(JSONRPCClient):\n    # This dummy client just prints the request payload\n    # In a real app, this method would send an HTTP POST request\n    # and return the response text.\n    def _send_request(self, request_str):\n        print(f\"\\n--- Client sending request payload ---\\n{request_str}\")\n        # In a real scenario, you'd send this via HTTP and get a response.\n        # For this quickstart, we'll return a simulated server response.\n        \n        # Simulate the server handling this request\n        simulated_response_object = JSONRPCResponseManager.handle(request_str, dispatcher)\n        if simulated_response_object:\n            return json.dumps(simulated_response_object.json)\n        return json.dumps({\n            \"jsonrpc\": \"2.0\",\n            \"error\": {\"code\": -32000, \"message\": \"Server error during simulation\"},\n            \"id\": None\n        })\n\nprint(\"\\n--- Client constructing and simulating a call ---\")\nclient = MyDummyTransportClient(service_url=\"http://example.com/api\") # URL is dummy for this example\nresult = client.call(\"greet\", name=\"Alice\")\nprint(f\"Client received simulated result: {result}\")\n\n# Example of a client calling an RPC method that causes an error on the server\nprint(\"\\n--- Client constructing and simulating an error-causing call ---\")\nerror_result = client.call(\"secure_data\", token=\"bad_token\")\nprint(f\"Client received simulated error result: {error_result}\")\n","lang":"python","description":"This quickstart demonstrates the core functionality of `json-rpc`: how `JSONRPCResponseManager` dispatches incoming JSON-RPC requests on the server side and how `JSONRPCClient` constructs outgoing requests. It includes examples of successful calls, parameter passing, and error handling. Note that the actual network transport (e.g., HTTP POST) needs to be implemented separately, often using libraries like `requests` for clients or `werkzeug`/Flask for servers."},"warnings":[{"fix":"Use a library like `requests` for client transport or `werkzeug`, Flask, or Django for server-side HTTP/WSGI transport. The library's quickstart often implicitly demonstrates integration with `werkzeug` for servers.","message":"The `json-rpc` library provides the JSON-RPC protocol implementation but *does not* handle the network transport (e.g., HTTP, TCP, WebSockets) itself. You must integrate it with a transport layer library.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always use `import jsonrpc` or `from jsonrpc.<module> import ...` in your Python code.","message":"The package is installed via `pip install json-rpc` but its top-level import name is `jsonrpc` (e.g., `import jsonrpc` or `from jsonrpc.manager import ...`). This hyphen-to-underscore naming convention can sometimes cause `ModuleNotFoundError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"When raising exceptions in your dispatcher methods, ensure they carry meaningful messages. Consider subclassing `jsonrpc.manager.JSONRPCError` for custom error codes or providing a custom error handling function to the `JSONRPCResponseManager` if more fine-grained control is needed over error responses.","message":"Custom error handling on the server side requires careful consideration. `JSONRPCResponseManager` automatically catches exceptions raised by dispatched methods and converts them into standard JSON-RPC error objects. Developers should be aware of how their custom exceptions map to the protocol's error codes and messages.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure the package is installed with `pip install json-rpc` and that your import statements use `import jsonrpc` or `from jsonrpc.<submodule> import ...`.","cause":"The Python interpreter cannot find the `jsonrpc` module. This often happens if the package `json-rpc` was not installed, or if an incorrect import name (e.g., `json_rpc`) was used.","error":"ModuleNotFoundError: No module named 'jsonrpc'"},{"fix":"Call `JSONRPCResponseManager.handle(request_string, dispatcher_object)` ensuring both arguments are provided and correctly typed.","cause":"The `handle` method of `JSONRPCResponseManager` expects two arguments: the raw JSON-RPC request string and a dispatcher (a dictionary or object mapping method names to functions).","error":"TypeError: JSONRPCResponseManager.handle() takes exactly 2 arguments (1 given)"},{"fix":"Verify that the incoming request payload is a well-formed JSON string. This error often indicates a client sending invalid data or a transport issue corrupting the payload.","cause":"The input string passed to `JSONRPCResponseManager.handle` is not valid JSON, or contains malformed data, preventing `json.loads()` from parsing it.","error":"json.decoder.JSONDecodeError: Expecting value: line X column Y (char Z)"}]}