Skip to content

Sanic

from sanic import HTTPResponse, Request, Sanic

from jsonrpcserver import Result, Success, async_dispatch, method

app = Sanic("jsonrpc")
# Bigger requests get 413 Request Entity Too Large. Sanic's default is 100 MB.
app.config.REQUEST_MAX_SIZE = 1_000_000


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


@app.post("/")
async def index(request: Request) -> HTTPResponse:
    # max_batch_size: see the Security page.
    if response := await async_dispatch(request.body.decode(), max_batch_size=100):
        return HTTPResponse(response, content_type="application/json")
    return HTTPResponse(status=204)


if __name__ == "__main__":
    app.run(host="localhost", port=8000, single_process=True)

Sanic refuses a body bigger than REQUEST_MAX_SIZE with 413. Its default is 100 MB, so the example sets a smaller one. max_batch_size limits how many requests one batch can hold. See Security.

To give methods the request, pass it as context: await async_dispatch(..., context=request). See Context.

single_process=True keeps the example simple. Sanic's own docs cover running it with workers in production.

Try it

Save the example as sanic_server.py, install Sanic (pip install sanic), and run it:

python sanic_server.py

Then send it a request from another terminal:

curl -s -H 'Content-Type: application/json' -d '{"jsonrpc": "2.0", "method": "ping", "id": 1}' http://localhost:8000/
Output
{"jsonrpc": "2.0", "result": "pong", "id": 1}

The jsonrpcclient quickstart sends the same request from Python.