Skip to content

API reference

This page is generated from the docstrings in the source code, so it matches the code on the main branch.

Everything in the first five sections can be imported from the package itself, for example from jsonrpcserver import Success, dispatch, method. The two dispatch_to_json entries are the exception: they're the functions behind dispatch and async_dispatch, and live in jsonrpcserver.main and jsonrpcserver.async_main. The other public names are in jsonrpcserver.response, jsonrpcserver.result, jsonrpcserver.codes, jsonrpcserver.methods and jsonrpcserver.sentinels. Anything not listed here is internal and can change in any release.

In the signatures, context=NOCONTEXT means "no context": methods get only the request's params. data=NODATA means the error has no data member.

Methods and results

method

method(f: F, name: str | None = None) -> F
method(f: None = None, name: str | None = None) -> Callable[[F], F]
method(f: Callable[..., Any] | None = None, name: str | None = None) -> Any

Register a function as a JSON-RPC method.

The function is added to global_methods, which the dispatch functions use when they're called without methods. It's returned unchanged, so you can still call it yourself, and type checkers see its real signature (from 5.0.10). A method with the same name as an earlier one replaces it, without a warning.

Use it with or without arguments:

@method
def ping() -> Result:
    return Success("pong")

@method(name="sum")
def add(a: int, b: int) -> Result:
    return Success(a + b)

Parameters:

  • f (Callable[..., Any] | None, default: None ) –

    The function. Leave it out to pass name.

  • name (str | None, default: None ) –

    The name requests use to call the method. The default is the function's name.

Returns:

  • Any –

    The function itself, or, when called with only name, a decorator.

Raises:

  • ValueError –

    If the name starts with "rpc.". The JSON-RPC spec reserves those names. Changed in 6.0: 5.0.10 warned and added the method anyway.

Success

Success(result: Any = None) -> SuccessResult

A successful result. Return it from a method.

Parameters:

  • result (Any, default: None ) –

    The value for the response's result member. It can be anything the serializer handles. The default, None, is sent as null.

Returns:

Example

from jsonrpcserver import Result, Success, dispatch def ping() -> Result: ... return Success("pong") dispatch('{"jsonrpc": "2.0", "method": "ping", "id": 1}', {"ping": ping}) '{"jsonrpc": "2.0", "result": "pong", "id": 1}'

Error

Error(code: int, message: str, data: Any = NODATA) -> ErrorResult

An error result. Return it from a method to send an error response.

It's sent as it is, whatever debug is, so don't put secrets in it.

Parameters:

  • code (int) –

    The error code, an integer. The spec reserves -32768 to -32000 for its own errors, so pick other numbers for yours.

  • message (str) –

    A short description of the error, as a string.

  • data (Any, default: NODATA ) –

    Extra information for the client, such as details of what went wrong. If it isn't given, the response has no data member.

Returns:

Raises:

  • TypeError –

    If code isn't an int or message isn't a str. Changed in 6.0: 5.0.10 warned and sent the error as given.

Example

from jsonrpcserver import Error, Result, dispatch_to_serializable def fail() -> Result: ... return Error(1, "It failed", {"reason": "example"}) request = '{"jsonrpc": "2.0", "method": "fail", "id": 1}' dispatch_to_serializable(request, {"fail": fail})["error"] {'code': 1, 'message': 'It failed', 'data': {'reason': 'example'}}

InvalidParams

InvalidParams(data: Any = NODATA) -> ErrorResult

An Invalid params error: Error(-32602, "Invalid params", data).

Return it when the arguments have the right shape but a bad value. jsonrpcserver already sends this error when the arguments don't fit the method's signature.

Parameters:

  • data (Any, default: NODATA ) –

    What was wrong, for the client. If it isn't given, the response has no data member.

Returns:

Example

from jsonrpcserver import InvalidParams, Result, Success from jsonrpcserver import dispatch_to_serializable def rate(stars: int) -> Result: ... if stars not in range(1, 6): ... return InvalidParams("Stars must be 1 to 5") ... return Success() request = '{"jsonrpc": "2.0", "method": "rate", "params": [6], "id": 1}' dispatch_to_serializable(request, {"rate": rate})["error"]

JsonRpcError

JsonRpcError(code: int, message: str, data: Any = NODATA)

Bases: Exception

Raise it in a method, or in anything a method calls, to send an error response.

It's the same as returning Error(code, message, data), but it works from deep inside other functions. Like Error, it's sent as it is, whatever debug is.

Parameters:

  • code (int) –

    The error code, an integer.

  • message (str) –

    A short description of the error, as a string.

  • data (Any, default: NODATA ) –

    Extra information for the client. If it isn't given, the response has no data member.

Raises:

  • TypeError –

    If code isn't an int or message isn't a str. Changed in 6.0: 5.0.10 warned instead.

Example

from jsonrpcserver import Result, dispatch_to_serializable def withdraw(amount: int) -> Result: ... raise JsonRpcError(2, "Insufficient funds", {"balance": 10}) request = '{"jsonrpc": "2.0", "method": "withdraw", "params": [5], "id": 1}' dispatch_to_serializable(request, {"withdraw": withdraw})["error"] {'code': 2, 'message': 'Insufficient funds', 'data': {'balance': 10}}

Result module-attribute

The return type of a method: what Success, Error and InvalidParams give.

Use it as the return annotation of your methods. To tell the two apart, check isinstance(result, ErrorResult). Changed in 6.0: 5.x wrapped these in oslash's Right and Left.

Dispatch

dispatch module-attribute

dispatch = dispatch_to_json

Another name for dispatch_to_json, and the one most code uses.

jsonrpcserver.main.dispatch_to_json

dispatch_to_json(request: str, methods: MethodsArgument | None = None, *, context: Any = NOCONTEXT, deserializer: Callable[[str], Deserialized] = default_deserializer, validator: Callable[[Deserialized], object] = default_validator, debug: bool = False, max_batch_size: int | None = DEFAULT_MAX_BATCH_SIZE, serializer: Callable[[dict[str, Any] | list[dict[str, Any]] | str], str] = default_serializer) -> str

Dispatch a request and give the response as a JSON string.

This is dispatch, the function most code uses. Send the string back to the client. An empty string means there's nothing to send back: the request was a notification, or a batch of only notifications. Over HTTP, send status 204 with no body for that.

Parameters:

  • request (str) –

    The JSON-RPC request string.

  • methods (MethodsArgument | None, default: None ) –

    The same as for dispatch_to_response.

  • context (Any, default: NOCONTEXT ) –

    The same as for dispatch_to_response.

  • deserializer (Callable[[str], Deserialized], default: default_deserializer ) –

    The same as for dispatch_to_response.

  • validator (Callable[[Deserialized], object], default: default_validator ) –

    The same as for dispatch_to_response.

  • debug (bool, default: False ) –

    The same as for dispatch_to_response.

  • max_batch_size (int | None, default: DEFAULT_MAX_BATCH_SIZE ) –

    The same as for dispatch_to_response.

  • serializer (Callable[[dict[str, Any] | list[dict[str, Any]] | str], str], default: default_serializer ) –

    The function that turns the response into a string. The default is json.dumps with allow_nan=False, so a result holding NaN or Infinity gives an Internal error instead of invalid JSON (new in 5.0.10). If the serializer raises for a response, say because the method returned a datetime, that response becomes an Internal error and the rest of a batch is sent as usual.

Returns:

  • str –

    The response as a JSON string, or "" if there's nothing to send back.

Raises:

  • ValueError –

    If max_batch_size isn't None or a positive int.

Example

from jsonrpcserver import Result, Success, dispatch def ping() -> Result: ... return Success("pong") dispatch('{"jsonrpc": "2.0", "method": "ping", "id": 1}', {"ping": ping}) '{"jsonrpc": "2.0", "result": "pong", "id": 1}'

dispatch_to_serializable

dispatch_to_serializable(request: str, methods: MethodsArgument | None = None, *, context: Any = NOCONTEXT, deserializer: Callable[[str], Deserialized] = default_deserializer, validator: Callable[[Deserialized], object] = default_validator, debug: bool = False, max_batch_size: int | None = DEFAULT_MAX_BATCH_SIZE) -> dict[str, Any] | list[dict[str, Any]] | None

Dispatch a request and give the response as a dict.

Use it when your framework serializes the response itself, such as a Django JsonResponse, or when you want to inspect it.

Parameters:

  • request (str) –

    The JSON-RPC request string.

  • methods (MethodsArgument | None, default: None ) –

    The same as for dispatch_to_response.

  • context (Any, default: NOCONTEXT ) –

    The same as for dispatch_to_response.

  • deserializer (Callable[[str], Deserialized], default: default_deserializer ) –

    The same as for dispatch_to_response.

  • validator (Callable[[Deserialized], object], default: default_validator ) –

    The same as for dispatch_to_response.

  • debug (bool, default: False ) –

    The same as for dispatch_to_response.

  • max_batch_size (int | None, default: DEFAULT_MAX_BATCH_SIZE ) –

    The same as for dispatch_to_response.

Returns:

  • dict[str, Any] | list[dict[str, Any]] | None –

    The response as a dict, a list of dicts for a batch, or None if there's nothing to send back.

Raises:

  • ValueError –

    If max_batch_size isn't None or a positive int.

Example

from jsonrpcserver import Result, Success, dispatch_to_serializable def ping() -> Result: ... return Success("pong") dispatch_to_serializable( ... '{"jsonrpc": "2.0", "method": "ping", "id": 1}', methods={"ping": ping} ... )

dispatch_to_response

dispatch_to_response(request: str, methods: MethodsArgument | None = None, *, context: Any = NOCONTEXT, deserializer: Callable[[str], Deserialized] = default_deserializer, validator: Callable[[Deserialized], object] = default_validator, post_process: Callable[[Response], Any] = identity, debug: bool = False, max_batch_size: int | None = DEFAULT_MAX_BATCH_SIZE) -> Response | list[Response] | None

Dispatch a request and give the response as Response objects.

Most code wants dispatch (a JSON string) or dispatch_to_serializable (dicts) instead. Use this one to inspect or change responses before they're serialized.

Each Response is a SuccessResponse or an ErrorResponse, frozen dataclasses with the response's fields. Check isinstance(response, ErrorResponse) to tell them apart. Changed in 6.0: 5.x wrapped them in oslash's Right and Left.

Parameters:

  • request (str) –

    The JSON-RPC request string.

  • methods (MethodsArgument | None, default: None ) –

    The methods requests can call, as a dict (or any mapping) of names to functions. The default is the dict that @method fills in, jsonrpcserver.methods.global_methods.

  • context (Any, default: NOCONTEXT ) –

    If given, it's passed as the first argument to every method. The client can't see or set it.

  • deserializer (Callable[[str], Deserialized], default: default_deserializer ) –

    The function that parses the request string. The default, default_deserializer, is json.loads that also rejects NaN, Infinity and numbers too big for a float (changed in 6.0). If it raises, the client gets a -32700 Parse error whose data is the exception message.

  • validator (Callable[[Deserialized], object], default: default_validator ) –

    The function that checks a parsed request against the JSON-RPC spec. It should raise an exception, of any kind, if the request is invalid. In a batch it's called once for each request (new in 5.0.10). The default checks the JSON-RPC 2.0 rules (jsonrpcserver.validator). lambda _: None turns validation off.

  • post_process (Callable[[Response], Any], default: identity ) –

    A function applied to each Response before it's returned.

  • debug (bool, default: False ) –

    If True, the error response for an exception a method doesn't catch includes the exception message in data. The default leaves data out, because exception messages can contain passwords, file paths and other details a client shouldn't see. The exception is logged either way. New in 5.0.10.

  • max_batch_size (int | None, default: DEFAULT_MAX_BATCH_SIZE ) –

    The most requests a batch may hold. A bigger batch gets a single -32600 Invalid request response, and none of it is run. The default is 100 (DEFAULT_MAX_BATCH_SIZE). None means no limit. New in 5.0.10. Changed in 6.0: 5.x had no limit by default.

Returns:

  • Response | list[Response] | None –

    A Response for a single request, a list of Responses for a batch, or None if there's nothing to send back (a notification, or a batch of only notifications). With post_process, whatever it returns for each.

Raises:

  • ValueError –

    If max_batch_size isn't None or a positive int. Requests never raise: a bad request or a failing method gives an error response.

Async dispatch

async_dispatch module-attribute

async_dispatch = dispatch_to_json

Another name for dispatch_to_json. The package exports it as async_dispatch.

jsonrpcserver.async_main.dispatch_to_json async

dispatch_to_json(request: str, methods: MethodsArgument | None = None, *, context: Any = NOCONTEXT, deserializer: Callable[[str], Deserialized] = default_deserializer, validator: Callable[[Deserialized], object] = default_validator, debug: bool = False, max_batch_size: int | None = DEFAULT_MAX_BATCH_SIZE, max_concurrency: int | None = None, serializer: Callable[[dict[str, Any] | list[dict[str, Any]] | None], str] = default_serializer) -> str

Dispatch a request and give the response as a JSON string. Async.

This is async_dispatch, the async version of dispatch. Methods can be async functions or plain ones (plain ones work from 5.0.10). A plain method runs on the event loop, so a slow one holds up every other request.

Parameters:

  • request (str) –

    The JSON-RPC request string.

  • methods (MethodsArgument | None, default: None ) –

    The same as for dispatch_to_response.

  • context (Any, default: NOCONTEXT ) –

    The same as for dispatch_to_response.

  • deserializer (Callable[[str], Deserialized], default: default_deserializer ) –

    The same as for dispatch_to_response.

  • validator (Callable[[Deserialized], object], default: default_validator ) –

    The same as for dispatch_to_response.

  • debug (bool, default: False ) –

    The same as for dispatch_to_response.

  • max_batch_size (int | None, default: DEFAULT_MAX_BATCH_SIZE ) –

    The same as for dispatch_to_response.

  • max_concurrency (int | None, default: None ) –

    The same as for async_dispatch_to_response.

  • serializer (Callable[[dict[str, Any] | list[dict[str, Any]] | None], str], default: default_serializer ) –

    The same as for dispatch.

Returns:

  • str –

    The response as a JSON string, or "" if there's nothing to send back.

Raises:

  • ValueError –

    If max_batch_size or max_concurrency isn't None or a positive int.

Example

import asyncio from jsonrpcserver import Result, Success, async_dispatch async def ping() -> Result: ... return Success("pong") request = '{"jsonrpc": "2.0", "method": "ping", "id": 1}' asyncio.run(async_dispatch(request, {"ping": ping})) '{"jsonrpc": "2.0", "result": "pong", "id": 1}'

async_dispatch_to_serializable async

async_dispatch_to_serializable(request: str, methods: MethodsArgument | None = None, *, context: Any = NOCONTEXT, deserializer: Callable[[str], Deserialized] = default_deserializer, validator: Callable[[Deserialized], object] = default_validator, debug: bool = False, max_batch_size: int | None = DEFAULT_MAX_BATCH_SIZE, max_concurrency: int | None = None) -> dict[str, Any] | list[dict[str, Any]] | None

Dispatch a request and give the response as a dict. Async.

The async version of dispatch_to_serializable, imported from the package as async_dispatch_to_serializable.

Parameters:

  • request (str) –

    The JSON-RPC request string.

  • methods (MethodsArgument | None, default: None ) –

    The same as for dispatch_to_response.

  • context (Any, default: NOCONTEXT ) –

    The same as for dispatch_to_response.

  • deserializer (Callable[[str], Deserialized], default: default_deserializer ) –

    The same as for dispatch_to_response.

  • validator (Callable[[Deserialized], object], default: default_validator ) –

    The same as for dispatch_to_response.

  • debug (bool, default: False ) –

    The same as for dispatch_to_response.

  • max_batch_size (int | None, default: DEFAULT_MAX_BATCH_SIZE ) –

    The same as for dispatch_to_response.

  • max_concurrency (int | None, default: None ) –

    The same as for async_dispatch_to_response.

Returns:

  • dict[str, Any] | list[dict[str, Any]] | None –

    The response as a dict, a list of dicts for a batch, or None if there's nothing to send back.

Raises:

  • ValueError –

    If max_batch_size or max_concurrency isn't None or a positive int.

async_dispatch_to_response async

async_dispatch_to_response(request: str, methods: MethodsArgument | None = None, *, context: Any = NOCONTEXT, deserializer: Callable[[str], Deserialized] = default_deserializer, validator: Callable[[Deserialized], object] = default_validator, post_process: Callable[[Response], Any] = identity, debug: bool = False, max_batch_size: int | None = DEFAULT_MAX_BATCH_SIZE, max_concurrency: int | None = None) -> Response | Iterable[Response] | None

Dispatch a request and give the response as Response objects. Async.

The async version of dispatch_to_response, imported from the package as async_dispatch_to_response. It takes the same arguments.

Parameters:

  • request (str) –

    The JSON-RPC request string.

  • methods (MethodsArgument | None, default: None ) –

    The same as for dispatch_to_response.

  • context (Any, default: NOCONTEXT ) –

    The same as for dispatch_to_response.

  • deserializer (Callable[[str], Deserialized], default: default_deserializer ) –

    The same as for dispatch_to_response.

  • validator (Callable[[Deserialized], object], default: default_validator ) –

    The same as for dispatch_to_response.

  • post_process (Callable[[Response], Any], default: identity ) –

    The same as for dispatch_to_response.

  • debug (bool, default: False ) –

    The same as for dispatch_to_response.

  • max_batch_size (int | None, default: DEFAULT_MAX_BATCH_SIZE ) –

    The same as for dispatch_to_response. Every request in a batch runs at the same time, so a limit matters even more here.

  • max_concurrency (int | None, default: None ) –

    The most requests of a batch that run at the same time. The rest wait their turn. The default, None, runs them all at once. Use it when each request opens a database connection or calls an API with a rate limit. Async only, because dispatch runs a batch one request at a time. New in 6.0.

Returns:

  • Response | Iterable[Response] | None –

    A Response for a single request, a list of Responses for a batch, or None if there's nothing to send back. The type hint says Iterable for a batch, but it's a list.

Raises:

  • ValueError –

    If max_batch_size or max_concurrency isn't None or a positive int.

Development server

serve

serve(name: str = 'localhost', port: int = 5000) -> None

Serve the methods registered with @method over HTTP. For development only.

It answers POST requests on any path with dispatch, sends 204 No Content for a notification, and runs each request in its own thread. It runs until the process is stopped, for example with Ctrl+C.

When it starts, it logs where it's listening on the jsonrpcserver.server logger. If logging isn't configured, it writes that line to stderr instead (new in 5.0.10). Each request is logged at INFO level.

It has no TLS, no authentication and no request size limit. It uses dispatch's defaults, so a batch may hold up to 100 requests. Put dispatch behind a real web server or framework in production.

Parameters:

  • name (str, default: 'localhost' ) –

    The host name or address to listen on. The default, "localhost", accepts only local connections. Pass "" to listen on every network interface, so other machines can connect. Changed in 6.0: 5.x listened on every interface by default.

  • port (int, default: 5000 ) –

    The port to listen on.

Example
from jsonrpcserver import Result, Success, method, serve

@method
def ping() -> Result:
    return Success("pong")

serve("localhost", 8000)

Version

__version__ module-attribute

__version__ = '6.0.0rc1'

The version of jsonrpcserver, as a string. Added in 5.0.10.

Responses

Response module-attribute

What dispatch_to_response gives for each request.

A SuccessResponse or an ErrorResponse. Check isinstance(response, ErrorResponse) to tell them apart, or turn one into a dict with to_dict. Changed in 6.0: 5.x wrapped these in oslash's Right and Left.

SuccessResponse dataclass

SuccessResponse(result: Any, id: Any)

A successful response: the method's result and the request's id.

ErrorResponse dataclass

ErrorResponse(code: int, message: str, data: Any, id: Any)

An error response: the error's code, message and data, and the request's id.

data is NODATA when there's no data, so it's left out of the response. id is None when the request couldn't be read, as the spec requires.

to_dict

to_dict(response: Response) -> dict[str, Any]

Turn a Response into a JSON-RPC response dict.

Parameters:

  • response (Response) –

    A Response from dispatch_to_response.

Returns:

  • dict[str, Any] –

    The response as a dict, ready for json.dumps.

Example

from jsonrpcserver import Result, Success, dispatch_to_response def ping() -> Result: ... return Success("pong") request = '{"jsonrpc": "2.0", "method": "ping", "id": 1}' to_dict(dispatch_to_response(request, {"ping": ping}))

to_success_dict

to_success_dict(response: SuccessResponse) -> dict[str, Any]

Turn a SuccessResponse into a JSON-RPC response dict.

to_error_dict

to_error_dict(response: ErrorResponse) -> dict[str, Any]

Turn an ErrorResponse into a JSON-RPC response dict, leaving out missing data.

to_serializable

to_serializable(response: Response | list[Response] | None) -> Deserialized | None

Turn a Response, a list of them or None into a dict, a list of dicts or None.

Results

SuccessResult dataclass

SuccessResult(result: Any = None)

A successful result: what Success returns. Changed in 6.0: it's the Result itself, not an oslash Right around it.

ErrorResult dataclass

ErrorResult(code: int, message: str, data: Any = NODATA)

An error result: what Error and InvalidParams return. Changed in 6.0: it's the Result itself, not an oslash Left around it.

data is NODATA when there's no data, so it's left out of the response.

Error codes

The error codes jsonrpcserver sends.

The first five are defined by the spec: https://www.jsonrpc.org/specification#error_object

ERROR_PARSE_ERROR module-attribute

ERROR_PARSE_ERROR = -32700

The request isn't valid JSON (or the deserializer raised).

ERROR_INVALID_REQUEST module-attribute

ERROR_INVALID_REQUEST = -32600

The JSON isn't a valid request object, or a batch is empty or too big.

ERROR_METHOD_NOT_FOUND module-attribute

ERROR_METHOD_NOT_FOUND = -32601

No method has that name.

ERROR_INVALID_PARAMS module-attribute

ERROR_INVALID_PARAMS = -32602

The params don't fit the method's signature, or the method said they're invalid.

ERROR_INTERNAL_ERROR module-attribute

ERROR_INTERNAL_ERROR = -32603

The method raised, returned something other than a Result, or its result could not be serialized.

ERROR_SERVER_ERROR module-attribute

ERROR_SERVER_ERROR = -32000

Something failed in jsonrpcserver itself, outside any method.

Other names

global_methods module-attribute

global_methods: dict[str, AnyMethod] = {}

The methods registered with @method, as a dict of names to functions.

The dispatch functions use it when they're called without methods. It's shared by the whole process, so every module that uses @method adds to it.

NODATA module-attribute

NODATA = Sentinel('NoData')

The default for data in Error and JsonRpcError: leave data out.

NOCONTEXT module-attribute

NOCONTEXT = Sentinel('NoContext')

The default for context: don't pass a context to methods.