jsonrpcclient

jsonrpcclient over ZeroMQ

Send JSON-RPC requests over ZeroMQ.

Installation

$ pip install jsonrpcclient pyzmq

Usage

Set the server details:

from jsonrpcclient.zmq_server import ZMQServer
server = ZMQServer('tcp://localhost:5555')

Send a request:

>>> response = server.request('cat', name='Mittens')
--> {"jsonrpc": "2.0", "method": "cat", "params": {"name": "Mittens"}, "id": 1}
<-- {"jsonrpc": "2.0", "result": "meow", "id": 1}

The first argument is the JSON-RPC method, followed by arguments to the method.

The return value is the payload, (the result part of the response message):

>>> response
'meow'

If you’re not interested in a response, use notify() instead of request().

Lower-Level

Send your own message with send():

>>> server.send({'jsonrpc': '2.0', 'method': 'cat', 'params': {'name': 'Mittens'}, 'id': 5})

A Request class is provided to simplify making a JSON-RPC message:

>>> Request('cat', name='Mittens', request_id=5)
{"jsonrpc": "2.0", "method": "cat", "params": {"name": "Mittens"}, "id": 5}

Send a Request:

>>> server.send(Request('cat', name='Mittens', request_id=5))
--> {"jsonrpc": "2.0", "method": "cat", "params": {"name": "Mittens"}, "id": 5}
<-- {"jsonrpc": "2.0", "result": "meow", "id": 5}
'meow'

There’s also a Notification class if you don’t need a response.

Batch requests

With batch requests you can send multiple requests in a single message:

>>> server.send([{'jsonrpc': '2.0', 'method': 'cat'}, {'jsonrpc': '2.0', 'method': 'dog'}])

Send multiple Request objects:

>>> server.send([Request('cat'), Request('dog')])

Using list comprehension to get the cube of ten numbers:

>>> server.send([Request('cube', i) for i in range(10)])

Unlike single requests, batch requests return the whole JSON-RPC response object, i.e. a list of responses for each request that had an id member.

The server may not support batch requests.

Exceptions

In the event of a communications problem, pyzmq raises zmq.ZMQError:

try:
    server.request('go')
except zmq.ZMQError as e:
    print(str(e))
jsonrpcclient.ParseError:
 Raised if the response is not valid JSON.
jsonschema.ValidationError:
 Raised if the response is valid JSON but not a valid JSON-RPC response.
jsonrpcclient.ReceivedErrorResponse:
 Raised if the server responded with an error message.

Logging

To see the JSON-RPC messages going back and forth, set the logging level to INFO:

import logging
logging.getLogger('jsonrpcclient').setLevel(logging.INFO)

Then add a basic handler:

logging.getLogger('jsonrpcclient').addHandler(logging.StreamHandler())

Or use custom handlers and formats:

request_format = '%(endpoint)s --> %(message)s'
response_format = '%(endpoint)s <-- %(message)s'

# Request log
request_handler = logging.StreamHandler()
request_handler.setFormatter(logging.Formatter(fmt=request_format))
logging.getLogger('jsonrpcclient.server.request').addHandler(
    request_handler)

# Response log
response_handler = logging.StreamHandler()
response_handler.setFormatter(logging.Formatter(fmt=response_format))
logging.getLogger('jsonrpcclient.server.response').addHandler(
    response_handler)

The request format has these fields:

endpoint:The server endpoint, eg. http://localhost:5555.
message:The JSON request (the body).

The response format has these fields:

endpoint:The server endpoint, eg. http://localhost:5555.
message:The JSON response (the body).