Home

Awesome

This is a fork

This repo is fork, but we didn't go anywhere :)

To the official repo, go here: https://github.com/permitio/fastapi_websocket_rpc


<p align="center"> <img src="https://i.ibb.co/m8jL6Zd/RPC.png" alt="RPC" border="0" width="50%" /> </p>

⚡ FASTAPI Websocket RPC

RPC over Websockets made easy, robust, and production ready

<a href="https://github.com/permitio/fastapi_websocket_rpc/actions?query=workflow%3ATests" target="_blank"> <img src="https://github.com/permitio/fastapi_websocket_rpc/workflows/Tests/badge.svg" alt="Tests"> </a> <a href="https://pypi.org/project/fastapi-websocket-rpc/" target="_blank"> <img src="https://img.shields.io/pypi/v/fastapi-websocket-rpc?color=%2331C654&label=PyPi%20package" alt="Package"> </a> <a href="https://pepy.tech/project/fastapi-websocket-rpc" target="_blank"> <img src="https://static.pepy.tech/personalized-badge/fastapi-websocket-rpc?period=total&units=international_system&left_color=black&right_color=blue&left_text=Downloads" alt="Downloads"> </a>

A fast and durable bidirectional JSON RPC channel over Websockets. The easiest way to create a live async channel between two nodes via Python (or other clients).

Supports and tested on Python >= 3.7

Installation 🛠️

pip install fastapi_websocket_rpc

RPC call example:

Say the server exposes an "add" method, e.g. :

class RpcCalculator(RpcMethodsBase):
    async def add(self, a, b):
        return a + b

Calling it is as easy as calling the method under the client's "other" property:

response = await client.other.add(a=1,b=2)
print(response.result) # 3

getting the response with the return value.

Usage example:

Server:

import uvicorn
from fastapi import FastAPI
from fastapi_websocket_rpc import RpcMethodsBase, WebsocketRPCEndpoint

# Methods to expose to the clients
class ConcatServer(RpcMethodsBase):
    async def concat(self, a="", b=""):
        return a + b
    
# Init the FAST-API app
app =  FastAPI()
# Create an endpoint and load it with the methods to expose
endpoint = WebsocketRPCEndpoint(ConcatServer())
# add the endpoint to the app
endpoint.register_route(app, "/ws")

# Start the server itself
uvicorn.run(app, host="0.0.0.0", port=9000)

Client

import asyncio
from fastapi_websocket_rpc import RpcMethodsBase, WebSocketRpcClient

async def run_client(uri):
    async with WebSocketRpcClient(uri, RpcMethodsBase()) as client:
        # call concat on the other side
        response = await client.other.concat(a="hello", b=" world")
        # print result
        print(response.result)  # will print "hello world"

# run the client until it completes interaction with server
asyncio.get_event_loop().run_until_complete(
    run_client("ws://localhost:9000/ws")
)

See the examples and tests folders for more server and client examples

Server calling client example:

What can I do with this?

Websockets are ideal to create bi-directional realtime connections over the web.

Concepts

Logging

fastapi-websocket-rpc provides a helper logging module to control how it produces logs for you. See fastapi_websocket_rpc/logger.py. Use logging_config.set_mode or the 'WS_RPC_LOGGING' environment variable to choose the logging method you prefer or override completely via default logging config.

example:

# set RPC to log like UVICORN
from fastapi_websocket_rpc.logger import logging_config, LoggingModes
logging_config.set_mode(LoggingModes.UVICORN)

Pull requests - welcome!