A flexible Python implementation of the JSON-RPC 2.0 protocol (currently server-side only).
- Full compliance with the JSON-RPC 2.0 specification
- No transport functionality
- Multiple method registration patterns (class-based, individual methods, lambda, etc.)
- Automatic & custom error handling capabilities
- Support for both string and bytes input
- Complete type hints (passes
mypy --strict
) - Extensive unit tests (full coverage)
- Semantic versioning adherence
To install the package, use pip:
pip install pyjsonrpc2
For more info, check the /examples
directory.
from pyjsonrpc2.server import JsonRpcServer, rpc_method, JsonRpcError
# Create a basic server
server = JsonRpcServer()
These are the main patterns for registering RPC methods. /examples/registering_methods.py
contains a few more.
- Class-based approach with decorators:
class MathServer(JsonRpcServer):
@rpc_method
def square(self, x):
return x**2
@rpc_method(name="cube")
def calculate_cube(self, x):
return x**3
server = MathServer()
- Adding individual methods using decorators:
@server.add_method
def add(a, b):
return a + b
- Adding methods with custom names:
def sub(a, b):
return a - b
server.add_method(sub, name="substract")
- Adding lambda functions:
server.add_method(lambda a, b: a % b, name="modulo")
Error handling features:
- Custom error codes for implementation-defined & application-defined errors through the
JsonRpcError
class - Automatic conversion of Python exceptions to JSON-RPC Internal error responses
- Support for additional error data in a structured format
- Built-in handling of protocol-level errors (invalid JSON, missing required fields, etc.)
- Error logging for debugging purposes
- Custom Implementation-Defined Errors:
class AdvancedMathServer(JsonRpcServer):
@rpc_method
def divide(self, a, b):
if b == 0:
raise JsonRpcError(
code=-32000,
message="Division by zero",
data={"numerator": a, "denominator": b}
)
return a / b
- Multiple Error Conditions:
@rpc_method
def factorial(self, n):
if not isinstance(n, int):
# Regular exceptions are caught and converted to Internal error responses
raise TypeError("n must be an integer")
if n < 0:
# Custom JSON-RPC errors with additional data
raise JsonRpcError(
code=-32001,
message="Invalid input for factorial",
data={"input": n, "reason": "Must be non-negative"}
)
# ... implementation ...
result = server.call('{"jsonrpc": "2.0", "method": "add", "params": [5, 3], "id": 1}')
result = server.call(b'{"jsonrpc": "2.0", "method": "subtract", "params": [5, 3], "id": 2}')
The simplest way to run tests is:
python -m unittest
As a more robust alternative, you can install tox
to automatically test across the supported python versions, then run:
tox -p
Please report any bugs or enhancement ideas using the issue tracker.
pyjsonrpc2
is licensed under the terms of the MIT License.