Skip to main content

pyjsonrpc2

PyPI PyPI - Python Version Tests GitHub PRs Welcome

A correct, transport-agnostic Python implementation of the JSON-RPC 2.0 protocol (currently server-side only).

Key features

  • Full compliance with the JSON-RPC 2.0 specification, batch requests and notifications included
  • Transport-agnostic: hand call() a raw request, send back the raw bytes it returns
  • Accepts str, bytes, bytearray and memoryview input
  • Multiple method registration patterns (constructor mapping, class-based, individual methods, lambda, etc.)
  • Automatic & custom error handling capabilities
  • Complete type hints (passes pyrefly on the strict preset)
  • Extensive unit tests (full coverage)
  • Semantic versioning adherence

Installation

pyjsonrpc2 requires Python 3.11 or later.

To install the package, use pip:

pip install pyjsonrpc2

Usage

For more info, check the examples/ directory.

Basic Server Creation

from pyjsonrpc2.server import JsonRpcServer, rpc_method, JsonRpcError

# Create a basic server
server = JsonRpcServer()

Method Registration Patterns

These are the main patterns for registering RPC methods. examples/registering_methods.py contains a few more.

  1. Passing a mapping of names to callables to the constructor:
server = JsonRpcServer({"get_version": lambda: "1.0"})
  1. 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()
  1. Registering the decorated methods of any other object, optionally under a prefix which keeps two objects exposing the same method names apart:
class MathUtils:
    @rpc_method
    def multiply(self, a, b):
        return a * b


server.add_object(MathUtils(), prefix="utils.")  # Registers "utils.multiply"
  1. Adding individual methods using decorators:
@server.add_method
def add(a, b):
    return a + b
  1. Adding methods with custom names:
def sub(a, b):
    return a - b


server.add_method(sub, name="subtract")
  1. Adding lambda functions:
server.add_method(lambda a, b: a % b, name="modulo")

Error Handling

Error handling features:

  • Custom error codes for implementation-defined & application-defined errors through the JsonRpcError class
  • Automatic conversion of Python exceptions to Internal error (-32603) responses
  • Automatic detection of argument mismatches, reported as Invalid params (-32602)
  • 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, on the pyjsonrpc2.server logger, at the ERROR level and with a traceback
  1. 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
  1. Multiple Error Conditions:
class AdvancedMathServer(JsonRpcServer):
    @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 ...

The data passed to JsonRpcError must be JSON serializable. A return value which is not is caught as well, and answered with an Internal error carrying the serialization failure as its data.

Request execution

call() returns the encoded response as bytes, or None when the client is owed no answer, i.e. for a single notification or for a batch holding only notifications.

server.call('{"jsonrpc": "2.0", "method": "add", "params": [5, 3], "id": 1}')
# b'{"jsonrpc":"2.0","id":1,"result":8}'

server.call(b'{"jsonrpc": "2.0", "method": "subtract", "params": [5, 3], "id": 2}')
# b'{"jsonrpc":"2.0","id":2,"result":2}'

# A notification (no "id"): nothing is owed to the client
server.call('{"jsonrpc": "2.0", "method": "add", "params": [5, 3]}')
# None

# A batch is answered with an array of the responses its elements are owed
server.call(
    '[{"jsonrpc": "2.0", "method": "add", "params": [1, 2], "id": 3},'
    ' {"jsonrpc": "2.0", "method": "modulo", "params": [7, 3], "id": 4}]'
)
# b'[{"jsonrpc":"2.0","id":3,"result":3},{"jsonrpc":"2.0","id":4,"result":1}]'

Extra keyword arguments for orjson.dumps() can be supplied through dumps_kwargs.

import orjson

server = JsonRpcServer(dumps_kwargs={"option": orjson.OPT_INDENT_2})

Tests

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

Issue tracker

Please report any bugs or enhancement ideas using the issue tracker.

License

pyjsonrpc2 is licensed under the terms of the MIT License.

Metadata

Release files for pyjsonrpc2 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyjsonrpc2 2.0.0
File Size Uploaded
pyjsonrpc2-2.0.0.tar.gz 10.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyjsonrpc2 2.0.0
File Interpreter ABI Platform
pyjsonrpc2-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.6 kB

Release files / pyjsonrpc2-2.0.0.tar.gz

Download URL pyjsonrpc2-2.0.0.tar.gz
Size 10.3 kB
Tags Source
SHA-256 checksum
How to use checksums
9da9799399b34db60db11e505d674c1a1a679f7fb3ef31c8827329a975f19e60
BLAKE2b-256 checksum
How to use checksums
56657df7d755ac7d755acb0ebbf8dd0743e4e11c315a22e7aa2c730053367267
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / pyjsonrpc2-2.0.0-py3-none-any.whl

Download URL pyjsonrpc2-2.0.0-py3-none-any.whl
Size 10.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
51c479b956ec8a6dc3647b030a3040c392670ac064db3f06140c0e5e4bdfb196
BLAKE2b-256 checksum
How to use checksums
0411c9bca41cded0cccf7660add6832532dd459615e295e9c2680f3f9092251c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release history Release notifications | RSS feed

3.0.0

2 release files

This release

2.0.0 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page