Skip to content

Tornado

import asyncio

from tornado import web

from jsonrpcserver import Result, Success, async_dispatch, method


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


class MainHandler(web.RequestHandler):
    async def post(self) -> None:
        # max_batch_size: see the Security page.
        request = self.request.body.decode()
        if response := await async_dispatch(request, max_batch_size=100):
            self.set_header("Content-Type", "application/json")
            self.write(response)
        else:
            self.set_status(204)


async def main() -> None:
    app = web.Application([(r"/", MainHandler)])
    # Tornado's default limit is 100 MB.
    app.listen(8000, address="localhost", max_body_size=1_000_000)
    await asyncio.Event().wait()


if __name__ == "__main__":
    asyncio.run(main())

Tornado refuses a body bigger than max_body_size with 400. Its default is 100 MB, so the example passes a smaller one to listen. max_batch_size limits how many requests one batch can hold. See Security.

To give methods the request, pass self.request as context. See Context.

Try it

Save the example as tornado_server.py, install Tornado (pip install tornado), and run it:

python tornado_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.