{"id":2858,"library":"ajsonrpc","title":"ajsonrpc","description":"ajsonrpc is an active, lightweight Python library (version 1.2.0) that provides an asynchronous implementation of the JSON-RPC 2.0 protocol and server capabilities, powered by asyncio. It functions as a successor to the `json-rpc` library, offering largely compatible code. It focuses on being vanilla Python with no external dependencies for its core functionality and has a release cadence driven by feature additions like new backend support.","status":"active","version":"1.2.0","language":"en","source_language":"en","source_url":"https://github.com/pavlov99/ajsonrpc","tags":["json-rpc","async","asyncio","server","protocol","backend"],"install":[{"cmd":"pip install ajsonrpc","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"JSONRPCResponseManager","correct":"from ajsonrpc.manager import JSONRPCResponseManager"},{"symbol":"Dispatcher","correct":"from ajsonrpc.dispatcher import Dispatcher"},{"symbol":"JSONRPCServerProtocol","correct":"from ajsonrpc.protocol import JSONRPCServerProtocol"},{"note":"For integrating with aiohttp framework","symbol":"AiohttpJSONRPCServer","correct":"from ajsonrpc.server.aiohttp import AiohttpJSONRPCServer"},{"note":"For integrating with Quart framework (added in v1.2.0)","symbol":"QuartJSONRPCServer","correct":"from ajsonrpc.server.quart import QuartJSONRPCServer"},{"note":"For integrating with Tornado framework","symbol":"TornadoJSONRPCServer","correct":"from ajsonrpc.server.tornado import TornadoJSONRPCServer"}],"quickstart":{"code":"import asyncio\nfrom ajsonrpc.manager import JSONRPCResponseManager\nfrom ajsonrpc.dispatcher import Dispatcher\nfrom ajsonrpc.protocol import JSONRPCServerProtocol\n\nclass MyJSONRPCServerProtocol(JSONRPCServerProtocol):\n    def __init__(self, manager):\n        super().__init__()\n        self._manager = manager\n\n    async def handle_request(self, payload):\n        # The manager handles parsing, dispatching to methods, and error handling\n        return await self._manager.get_payload_for_payload(payload)\n\ndef get_dispatcher():\n    dispatcher = Dispatcher()\n\n    @dispatcher.add_method\n    def add(a, b):\n        \"\"\"Adds two numbers.\"\"\"\n        return a + b\n\n    @dispatcher.add_method\n    async def say_hello(name=\"World\"):\n        \"\"\"Asynchronously greets a given name.\"\"\"\n        await asyncio.sleep(0.1) # Simulate async work\n        return f\"Hello, {name}!\"\n\n    return dispatcher\n\nasync def main():\n    dispatcher = get_dispatcher()\n    manager = JSONRPCResponseManager(dispatcher)\n\n    # Create a server factory that passes the manager instance\n    server_factory = lambda: MyJSONRPCServerProtocol(manager)\n    \n    # Start an asyncio TCP server\n    server = await asyncio.start_server(server_factory, '127.0.0.1', 8080)\n\n    addr = server.sockets[0].getsockname()\n    print(f\"Serving JSON-RPC on {addr}. Press Ctrl+C to stop.\")\n\n    async with server:\n        await server.serve_forever()\n\nif __name__ == \"__main__\":\n    try:\n        asyncio.run(main())\n    except KeyboardInterrupt:\n        print(\"\\nServer stopped.\")\n\n# Example usage (run this in another terminal while the server is running):\n# curl -X POST -H \"Content-Type: application/json\" \\\n#      -d '{\"jsonrpc\": \"2.0\", \"method\": \"add\", \"params\": [1, 2], \"id\": 1}' \\\n#      http://127.0.0.1:8080/\n#\n# curl -X POST -H \"Content-Type: application/json\" \\\n#      -d '{\"jsonrpc\": \"2.0\", \"method\": \"say_hello\", \"params\": {\"name\": \"Async User\"}, \"id\": 2}' \\\n#      http://127.0.0.1:8080/\n#\n# curl -X POST -H \"Content-Type: application/json\" \\\n#      -d '{\"jsonrpc\": \"2.0\", \"method\": \"non_existent_method\", \"params\": [], \"id\": 3}' \\\n#      http://127.0.0.1:8080/","lang":"python","description":"This quickstart demonstrates how to set up a basic `ajsonrpc` server using `asyncio.start_server`. It defines a `Dispatcher` to register RPC methods (both synchronous and asynchronous) and uses a `JSONRPCResponseManager` to handle incoming requests and generate responses. A custom `JSONRPCServerProtocol` bridges the `asyncio` transport with the `ajsonrpc` manager."},"warnings":[{"fix":"Refer to the GitHub repository's `ajsonrpc` and `json-rpc` documentation and examples for updated patterns, particularly regarding the `Dispatcher` and `JSONRPCResponseManager` usage.","message":"Major interface changes occurred between pre-1.0.0 versions (0.x.x) and the stable 1.0.0 release. The 0.1.0 release was explicitly marked with an 'unstable interface,' and 1.0.0a was a 'Freezing interface' release. Users upgrading from older 0.x.x versions should review their code, especially around protocol handling and manager initialization, as direct compatibility is not guaranteed.","severity":"breaking","affected_versions":"<1.0.0"},{"fix":"When initializing `JSONRPCResponseManager`, set `verbose_exceptions=True` (e.g., `manager = JSONRPCResponseManager(dispatcher, verbose_exceptions=True)`).","message":"By default, `JSONRPCResponseManager` returns a generic `ServerError` without detailed exception information for security reasons. If your application relies on verbose error reporting (e.g., for debugging in non-production environments), you must explicitly configure the manager to include exception details.","severity":"gotcha","affected_versions":">=1.1.0"},{"fix":"Always use `await` when calling asynchronous methods of `ajsonrpc` components, ensuring your server loop and request handling are fully `async` compatible.","message":"While `ajsonrpc` is designed for asynchronous operations, its core components like `JSONRPCResponseManager` can be misused in synchronous contexts. All methods intended for handling incoming RPC payloads (e.g., `get_payload_for_payload`) are `async` functions and must be `await`ed. Attempting to call them synchronously will lead to runtime errors or unexpected behavior.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}