Package: fastapi-websocket-rpc
⚡ FASTAPI Websocket RPCRPC over Websockets made easy, robust, and production readyA 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()wrapperConnections are kept alive with a configurable retry mechanism  (using Tenacity)As seen atPyCon IL 2021andEuroPython 2021Supports and tested on Python >= 3.7Installation 🛠️pip install fastapi_websocket_rpcRPC call example:Say the server exposes an "add" method, e.g. :classRpcCalculator(RpcMethodsBase):asyncdefadd(self,a,b):returna+bCalling it is as easy as calling the method under the client's "other" property:response=awaitclient.other.add(a=1,b=2)print(response.result)# 3getting the response with the return value.Usage example:Server:importuvicornfromfastapiimportFastAPIfromfastapi_websocket_rpcimportRpcMethodsBase,WebsocketRPCEndpoint# Methods to expose to the clientsclassConcatServer(RpcMethodsBase):asyncdefconcat(self,a="",b=""):returna+b# Init the FAST-API appapp=FastAPI()# Create an endpoint and load it with the methods to exposeendpoint=WebsocketRPCEndpoint(ConcatServer())# add the endpoint to the appendpoint.register_route(app,"/ws")# Start the server itselfuvicorn.run(app,host="0.0.0.0",port=9000)Clientimportasynciofromfastapi_websocket_rpcimportRpcMethodsBase,WebSocketRpcClientasyncdefrun_client(uri):asyncwithWebSocketRpcClient(uri,RpcMethodsBase())asclient:# call concat on the other sideresponse=awaitclient.other.concat(a="hello",b=" world")# print resultprint(response.result)# will print "hello world"# run the client until it completes interaction with serverasyncio.get_event_loop().run_until_complete(run_client("ws://localhost:9000/ws"))See theexamplesandtestsfolders for more server and client examplesServer calling client example:Clients can callclient.other.method()which is a shortcut forchannel.other.method()Servers also get the channel object and can call remote methods viachannel.other.method()See thebidirectional call examplefor 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 updatesRemote control mechanismPub / Sub (seefastapi_websocket_pubsub)Trigger events (see "tests/trigger_flow_test.py")Node negotiations (see "tests/advanced_rpc_test.py :: test_recursive_rpc_calls")ConceptsRpcChannel- implements the RPC-protocol over the websocketSending RpcRequests per method callCreating promises to track them (via unique call ids), and allow waiting for responsesExecuting methods on the remote side and serializing return values asReceiving RpcResponses and delivering them to waiting callersRpcMethods- 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 methodsNote currently only key-word arguments are supportedCheckout RpcUtilityMethods for example methods, which are also useful debugging utilitiesFoundations:Based onasynciofor the power of Python coroutinesServer Endpoint:Based onFAST-API: enjoy all the benefits of a full ASGI platform, including Async-io and dependency injections (for example to authenticate connections)Based onPydantic: 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 onTenacity: allowing configurable retries to keep to connection alivesee WebSocketRpcClient.init's retry_configBased on pythonwebsockets- a more comprehensive client than the one offered by Fast-apiLoggingfastapi-websocket-rpc provides a helper logging module to control how it produces logs for you.
Seefastapi_websocket_rpc/logger.py.
Uselogging_config.set_modeor 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 UVICORNfromfastapi_websocket_rpc.loggerimportlogging_config,LoggingModeslogging_config.set_mode(LoggingModes.UVICORN)Pull requests - welcome!Please include tests for new features