Skip to content

requests

requests serializes the dict that request returns when you pass it as json=:

import logging

import requests

from jsonrpcclient import Error, Ok, parse, request

response = requests.post("http://localhost:8000/", json=request("ping"), timeout=10)
response.raise_for_status()
parsed = parse(response.json())
if isinstance(parsed, Ok):
    print(parsed.result)
elif isinstance(parsed, Error):
    logging.error(parsed.message)

raise_for_status() raises requests.HTTPError for a 4xx or 5xx status. Without it, an HTML error page reaches response.json() and fails with requests.JSONDecodeError.

A batch

Send a list of requests, then check the shape of the reply before looping. A server that rejects the whole batch sends one error object instead of a list:

import logging

import requests

from jsonrpcclient import Error, Ok, parse, request

batch = [request("ping") for _ in range(3)]
response = requests.post("http://localhost:8000/", json=batch, timeout=10)
response.raise_for_status()
data = response.json()
if isinstance(data, dict):
    # The server rejected the whole batch. It sends one error object, not a list.
    logging.error("Batch rejected: %s", parse(data))
else:
    for parsed in parse(data):
        if isinstance(parsed, Ok):
            print(parsed.result)
        elif isinstance(parsed, Error):
            logging.error(parsed.message)

Batches explains this and the other edge cases.

Reusing a connection

For many calls, use a requests.Session so the connection stays open:

import requests

from jsonrpcclient import Error, Ok, parse, request

with requests.Session() as session:
    for _ in range(2):
        response = session.post(
            "http://localhost:8000/", json=request("ping"), timeout=10
        )
        response.raise_for_status()
        parsed = parse(response.json())
        if isinstance(parsed, Ok):
            print(parsed.result)
        elif isinstance(parsed, Error):
            print("Error:", parsed.message)
Output
pong
pong