Skip to main content

A fast and durable bidirectional JSON RPC channel over Websockets and FastApi.

Project description

⚡ FASTAPI Websocket RPC

RPC over Websockets made easy, robust, and production ready

Tests Package

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).

  • Both server and clients can easily expose Python methods that can be called by the other side. Method return values are sent back as RPC responses, which the other side can wait on.
  • Remote methods are easily called via the .other.method() wrapper
  • Connections are kept alive with a configurable retry mechanism (using Tenacity)

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:

  • Clients can call client.other.method()
    • which is a shortcut for channel.other.method()
  • Servers also get the channel object and can call remote methods via channel.other.method()
  • See the bidirectional call example for calling client from server and server events (e.g. on_connect).

What can I do with this?

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

  • Push updates
  • Remote control mechanism
  • Pub / Sub (see fastapi_websocket_pubsub)
  • Trigger events (see "tests/trigger_flow_test.py")
  • Node negotiations (see "tests/advanced_rpc_test.py :: test_recursive_rpc_calls")

Concepts

  • RpcChannel - implements the RPC-protocol over the websocket

    • Sending RpcRequests per method call
    • Creating promises to track them (via unique call ids), and allow waiting for responses
    • Executing methods on the remote side and serializing return values as
    • Receiving RpcResponses and delivering them to waiting callers
  • RpcMethods - classes passed to both client and server-endpoint inits to expose callable methods to the other side.

    • Simply derive from RpcMethodsBase and add your own async methods
    • Note currently only key-word arguments are supported
    • Checkout RpcUtilityMethods for example methods, which are also useful debugging utilities
  • Foundations:

    • Based on asyncio for the power of Python coroutines

    • Server Endpoint:

      • Based on FAST-API: enjoy all the benefits of a full ASGI platform, including Async-io and dependency injections (for example to authenticate connections)

      • Based on Pydnatic: easily serialize structured data as part of RPC requests and responses (see 'tests/basic_rpc_test.py :: test_structured_response' for an example)

    • Client :

      • Based on Tenacity: allowing configurable retries to keep to connection alive
        • see WebSocketRpcClient.init's retry_config
      • Based on python websockets - a more comprehensive client than the one offered by Fast-api

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!

  • Please include tests for new features

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_websocket_rpc-0.1.11.tar.gz (16.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fastapi_websocket_rpc-0.1.11-py3.8.egg (34.5 kB view details)

Uploaded Egg

fastapi_websocket_rpc-0.1.11-py3-none-any.whl (17.0 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_websocket_rpc-0.1.11.tar.gz.

File metadata

  • Download URL: fastapi_websocket_rpc-0.1.11.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.0 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.6

File hashes

Hashes for fastapi_websocket_rpc-0.1.11.tar.gz
Algorithm Hash digest
SHA256 9a850402c8dfeb3883caae74dd24a6175adeae45a4a905cc1d8ca2e1794e14c6
MD5 aaf110b11420bc71516ededf5ade858b
BLAKE2b-256 209578178152a4e8dd50d371ed889f8bb8d6bae74e168b20d8852766d21f7404

See more details on using hashes here.

File details

Details for the file fastapi_websocket_rpc-0.1.11-py3.8.egg.

File metadata

  • Download URL: fastapi_websocket_rpc-0.1.11-py3.8.egg
  • Upload date:
  • Size: 34.5 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.8.3

File hashes

Hashes for fastapi_websocket_rpc-0.1.11-py3.8.egg
Algorithm Hash digest
SHA256 9f4a40d4ac1185596d1c501fce0a77a39f0c7a12c0ba177ca143af8b621a573c
MD5 6bbf1a73792d48df55b43407479e1b5b
BLAKE2b-256 7cc6016429f18e2c3100ac0632edfe6a5558c2995c56b3fdf30018c1035562f5

See more details on using hashes here.

File details

Details for the file fastapi_websocket_rpc-0.1.11-py3-none-any.whl.

File metadata

  • Download URL: fastapi_websocket_rpc-0.1.11-py3-none-any.whl
  • Upload date:
  • Size: 17.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.0 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.6

File hashes

Hashes for fastapi_websocket_rpc-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 a8e46182f59ab6a8185b037059d4b82225d9f4d91ed6e4f5850d2fc1d0033116
MD5 cd1e1f2e0cd1252e60c317f04843b170
BLAKE2b-256 7fd9c898f61f53930b42152b4299c51ee75aad84c61405ee3a7253386fa96880

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page