Skip to main content

Basics

Built on Specifications

Python OpenRPC is built on multiple specifications.

JSON-RPC 2.0

The JSON-RPC 2.0 Spec is a transport agnostic spec which defines the properties of a JSON-RPC server. A JSON-RPC server will have methods that can be called remotely. The spec defines the format of requests expected by a JSON-RPC server to call a method and the format that the server responses must match.

OpenRPC

The OpenRPC spec defines a document for describing the methods and schemas used in a JSON-RPC server. It's like OpenAPI for JSON-RPC APIs. The OpenRPC document will list each method in the server along with the parameters expected by those method and the result it will produce. Like OpenAPI, it leverages JSON Schemas to describe types.

What Does This Framework Do?

This framework provides a class, RPCServer, that is used to register python functions as methods in an OpenRPC server. Once methods are registered the framework can parse JSON-RPC requests, call the appropriate function, wrap the function's return value in a JSON-RPC response and return it.

Usage

To register a method with the RPCServer use the @rpc.method() decorator on a function.

from openrpc import RPCServer

rpc = RPCServer(title="Demo Server", version="1.0.0")


@rpc.method()
def add(a: int, b: int) -> int:
return a + b

Process JSON-RPC Request

OpenRPC is transport agnostic. To use it, pass JSON-RPC requests as strings or byte strings to the process_request or process_request_async methods.

Calling process_request will parse the JSON-RPC request and call the appropriate function based on method name. Then the result of that function will be wrapped in a JSON-RPC response and returned as a string.

req = """
{
"id": 1,
"method": "add",
"params": {"a": 2, "b": 2},
"jsonrpc": "2.0"
}
"""
rpc.process_request(req) # '{"id":1,"result":4,"jsonrpc":"2.0"}'

Pydantic For Data Models

For data classes to work properly use Pydantic. RPCServer will use Pydantic for JSON serialization/deserialization when calling methods and for schema generation when getting docs with rpc.discover.

Pydantic Example

from openrpc import RPCServer
from pydantic import BaseModel

rpc = RPCServer(title="Demo Server", version="1.0.0")


class Vector3(BaseModel):
x: float = 1.0
y: float = 1.0
z: float = 1.0


@rpc.method()
def get_distance(a: Vector3, b: Vector3) -> Vector3:
return Vector3(
x=a.x - b.x,
y=a.y - b.y,
z=a.z - b.z,
)


req = """
{
"id": 1,
"method": "get_distance",
"params": [{"x": 3.0, "y": 5.0, "z": 7.0}, {"x": 1.0, "y": 1.0, "z": 1.0}],
"jsonrpc": "2.0"
}
"""
rpc.process_request(req) # '{"id":1,"result":{"x":2.0,"y":4.0,"z":6.0},"jsonrpc":"2.0"}'