Package: rpc.py
rpc.pyAn fast and powerful RPC framework based on ASGI/WSGI. Based on WSGI/ASGI, you can deploy the rpc.py server to any server and use http2 to get better performance. And based on httpx's support for multiple http protocols, the client can also use http/1.0, http/1.1 or http2.You can freely use ordinary functions and asynchronous functions for one-time response. You can also use generator functions or asynchronous generator functions to stream responses.InstallInstall from PyPi:pipinstallrpc.py# need use clientpipinstallrpc.py[client]# need use pydantic type hint or OpenAPI docspipinstallrpc.py[type]# need use msgpack to serializerpipinstallrpc.py[msgpack]# need use CBOR to serializerpipinstallrpc.py[cbor]# or install all dependenciespipinstallrpc.py[full]Install from github:pipinstallgit+https://github.com/abersheeran/rpc.py@setup.pyUsageServer side:UseASGImode to registerasync def...fromtypingimportAsyncGeneratorfromtyping_extensionsimportTypedDictimportuvicornfromrpcpyimportRPCapp=RPC(mode="ASGI")@app.registerasyncdefnone()->None:return@app.registerasyncdefsayhi(name:str)->str:returnf"hi{name}"@app.registerasyncdefyield_data(max_num:int)->AsyncGenerator[int,None]:foriinrange(max_num):yieldiD=TypedDict("D",{"key":str,"other-key":str})@app.registerasyncdefquery_dict(value:str)->D:return{"key":value,"other-key":value}if__name__=="__main__":uvicorn.run(app,interface="asgi3",port=65432)ORUseWSGImode to registerdef...fromtypingimportGeneratorfromtyping_extensionsimportTypedDictimportuvicornfromrpcpyimportRPCapp=RPC()@app.registerdefnone()->None:return@app.registerdefsayhi(name:str)->str:returnf"hi{name}"@app.registerdefyield_data(max_num:int)->Generator[int,None,None]:foriinrange(max_num):yieldiD=TypedDict("D",{"key":str,"other-key":str})@app.registerdefquery_dict(value:str)->D:return{"key":value,"other-key":value}if__name__=="__main__":uvicorn.run(app,interface="wsgi",port=65432)Client side:Notice: Regardless of whether the server uses the WSGI mode or the ASGI mode, the client can freely use the asynchronous or synchronous mode.Usehttpx.Client()mode to registerdef...fromtypingimportGeneratorfromtyping_extensionsimportTypedDictimporthttpxfromrpcpy.clientimportClientapp=Client(httpx.Client(),base_url="http://127.0.0.1:65432/")@app.remote_calldefnone()->None:...@app.remote_calldefsayhi(name:str)->str:...@app.remote_calldefyield_data(max_num:int)->Generator[int,None,None]:yieldD=TypedDict("D",{"key":str,"other-key":str})@app.remote_calldefquery_dict(value:str)->D:...ORUsehttpx.AsyncClient()mode to registerasync def...fromtypingimportAsyncGeneratorfromtyping_extensionsimportTypedDictimporthttpxfromrpcpy.clientimportClientapp=Client(httpx.AsyncClient(),base_url="http://127.0.0.1:65432/")@app.remote_callasyncdefnone()->None:...@app.remote_callasyncdefsayhi(name:str)->str:...@app.remote_callasyncdefyield_data(max_num:int)->AsyncGenerator[int,None]:yieldD=TypedDict("D",{"key":str,"other-key":str})@app.remote_callasyncdefquery_dict(value:str)->D:...Server as clientYou can also write two copies of code in one place. Just make sure thatserver.registeris executed beforeclient.remote_call.importhttpxfromrpcpyimportRPCfromrpcpy.clientimportClientserver=RPC()client=Client(httpx.Client(),base_url="http://127.0.0.1:65432/")@client.remote_call@server.registerdefsayhi(name:str)->str:returnf"hi{name}"if__name__=="__main__":importuvicornuvicorn.run(app,interface="wsgi",port=65432)Sub-routeIf you need to deploy the rpc.py server underexample.com/sub-route/*, you need to setRPC(prefix="/sub-route/")and modify theClient(base_path=https://example.com/sub-route/).SerializationCurrently supports three serializers, JSON, Pickle, Msgpack and CBOR. JSON is used by default. You can override the defaultJSONSerializerwith parameters.fromrpcpy.serializersimportPickleSerializer,MsgpackSerializer,CBORSerializerRPC(...,response_serializer=MsgpackSerializer(),)# OrClient(...,request_serializer=PickleSerializer(),)Type hint and OpenAPI DocThanks to the great work ofpydantic, which makes rpc.py allow you to use type annotation to annotate the types of function parameters and response values, and perform type verification and JSON serialization . At the same time, it is allowed to generate openapi documents for human reading.OpenAPI DocumentsIf you want to open the OpenAPI document, you need to initializeRPClike thisRPC(openapi={"title": "TITLE", "description": "DESCRIPTION", "version": "v1"}).Then, visit the"{prefix}openapi-docs"of RPC and you will be able to see the automatically generated OpenAPI documentation. (If you do not set theprefix, theprefixis"/")LimitationsCurrently, file upload is not supported, but you can do this by passing abytesobject.