WSRPC is the RPC over WebSocket for aiohttp

aiohttp, async, python-3-5, python3, websocket, websocket-client, websocket-server, ws
pip install wsrpc-aiohttp==3.2.0


WSRPC aiohttp

Github Actions


Latest Version

python wheel

Python Versions


Easy to use minimal WebSocket Remote Procedure Call library for aiohttp servers.

See online demo and documentation with examples.


  • Call server functions from the client side;
  • Call client functions from the server (for example to notify clients about events);
  • Async connection protocol: both server or client are able to call several functions and get responses as soon as each response would be ready in any order.
  • Fully async server-side functions;
  • Transfer any exceptions from a client side to the server side and vise versa;
  • Ready-to-use frontend-library without dependencies;
  • Thread-based websocket handler for writing fully-synchronous backend code (for synchronous database drivers etc.)
  • Protected server-side methods (cliens are not able to call methods, starting with underline directly);
  • Signals for introspection


Install via pip:

pip install wsrpc-aiohttp

You may want to install optional ujson library to speedup message serialization/deserialization:

pip install ujson

Python module provides client js library out of the box. But for pure javascript applications you can install standalone js client library using npm:

npm install @wsrpc/client


Backend code:

import logging
from time import time

import aiohttp.web
from wsrpc_aiohttp import Route, STATIC_DIR, WebSocketRoute, decorators

log = logging.getLogger(__name__)

# This class can be called by client.
# Connection object will have this class instance after calling route-alias.
class TestRoute(Route):
    # This method will be executed when client calls route-alias
    # for the first time.
    def init(self, **kwargs):
        # Python __init__ must be return "self".
        # This method might return anything.
        return kwargs

    # This method named by camelCase because the client can call it.
    async def getEpoch(self):

        # You can execute functions on the client side
        await self.do_notify()

        return time()

    # This method calls function on the client side
    async def do_notify(self):
        awesome = 'Somebody executed test1.getEpoch method!'
        await'notify', result=awesome)

app = aiohttp.web.Application()
app.router.add_route("*", "/ws/", WebSocketAsync)  # Websocket route
app.router.add_static('/js', STATIC_DIR)  # WSRPC js library
app.router.add_static('/', ".")  # Your static files

# Stateful request
# This is the route alias TestRoute as "test1"
WebSocketAsync.add_route('test1', TestRoute)

# Stateless request
WebSocketAsync.add_route('test2', lambda *a, **kw: True)

if __name__ == '__main__':
    aiohttp.web.run_app(app, port=8000)

Frontend code:

<script type="text/javascript" src="/js/wsrpc.min.js"></script>
    var url = (window.location.protocol==="https):"?"wss://":"ws://") + + '/ws/';
    RPC = new WSRPC(url, 8000);

    // Configure client API, that can be called from server
    RPC.addRoute('notify', function (data) {
        console.log('Server called client route "notify":', data);
        return data.result;

    // Call stateful route
    // After you call that route, server would execute 'notify' route on the
    // client, that is registered above.'test1.getEpoch').then(function (data) {
        console.log('Result for calling server route "test1.getEpoch": ', data);
    }, function (error) {

    // Call stateless method'test2').then(function (data) {
        console.log('Result for calling server route "test2"', data);


This software follows Semantic Versioning