Package: aio-nameko-proxy
aio-nameko-proxyA standalone nameko rpc proxy for asyncio and some wrappers for using nameko rpc proxy with asynchronous web frameworks(Sanic, fastapi).This project is based on aio-pika and reference the source code of official nameko project and aio-pika.installpipinstallaio-nameko-proxyexamples:standalone AIOClusterRpcProxyIf you want most of your messages to be persistent(default). Set the delivery mode parameter as
DeliveryMode.PERSISTENT, Call sw_dlm_call when you need to send a non-persistent message.importsslimportasynciofromaio_nameko_proxyimportAIOClusterRpcProxyfromaio_pikaimportDeliveryModeconfig={"AMQP_URI":"amqp://guest:guest@127.0.0.1:5672",# Required,"rpc_exchange":"nameko-rpc","time_out":30,"con_time_out":5,"delivery_mode":DeliveryMode.PERSISTENT,"serializer":"my_serializer","ACCEPT":["pickle","json","my_serializer"],"SERIALIZERS":{"my_serializer":{"encoder":"my_slizer.dumps","decoder":"my_slizer.loads","content_type":"my-content-type","content_encoding":"utf-8"}},# If SSL is configured, Remember to change the URI to TLS port. eg: "amqps://guest:guest@127.0.0.1:5671""AMQP_SSL":{'ca_certs':'certs/ca_certificate.pem',# or 'cafile': 'certs/ca_certificate.pem','certfile':'certs/client_certificate.pem','keyfile':'certs/client_key.pem','cert_reqs':ssl.CERT_REQUIRED}}asyncdefrun():asyncwithAIOClusterRpcProxy(config)asrpc:# time_out: the time_out of waitting the remote method result.# con_time_out: the time_out of connecting to the rabbitmq server or binding the queue, consume and so on.# persistent msg callresult=awaitrpc.rpc_demo_service.normal_rpc("demo")reply_obj=awaitrpc.rpc_demo_service.normal_rpc.call_async("demo")result=awaitreply_obj.result()# non-persistent msg callresult=awaitrpc.rpc_demo_service.normal_rpc.sw_dlm_call("demo")reply_obj=awaitrpc.rpc_demo_service.normal_rpc.sw_dlm_call_async("demo")result=awaitreply_obj.result()if__name__=='__main__':loop=asyncio.get_event_loop()loop.run_until_complete(run())If you want most of your messages to be non-persistent(persistent is default). Set the delivery mode parameter as
DeliveryMode.NOT_PERSISTENT, Call sw_dlm_call when you need to send a persistent message.importasynciofromaio_nameko_proxyimportAIOClusterRpcProxyfromaio_pikaimportDeliveryModeconfig={"AMQP_URI":"pyamqp://guest:guest@127.0.0.1:5672","rpc_exchange":"nameko-rpc","time_out":30,"con_time_out":5,"delivery_mode":DeliveryMode.NOT_PERSISTENT}asyncdefrun():asyncwithAIOClusterRpcProxy(config)asrpc:# non-persistent msg callresult=awaitrpc.rpc_demo_service.normal_rpc("demo")reply_obj=awaitrpc.rpc_demo_service.normal_rpc.call_async("demo")result=awaitreply_obj.result()# persistent msg callresult=awaitrpc.rpc_demo_service.normal_rpc.sw_dlm_call("demo")reply_obj=awaitrpc.rpc_demo_service.normal_rpc.sw_dlm_call_async("demo")result=awaitreply_obj.result()if__name__=='__main__':loop=asyncio.get_event_loop()loop.run_until_complete(run())AIOPooledClusterRpcProxyimportasynciofromaio_nameko_proxyimportAIOPooledClusterRpcProxyfromaio_pikaimportDeliveryModeconfig={"AMQP_URI":"pyamqp://guest:guest@127.0.0.1:5672","rpc_exchange":"nameko-rpc","time_out":30,"con_time_out":5,"pool_size":10,"initial_size":2,"delivery_mode":DeliveryMode.NOT_PERSISTENT}asyncdefrun():asyncwithAIOPooledClusterRpcProxy(config)asproxy_pool:asyncwithproxy_pool.acquire()asrpc:result=awaitrpc.rpc_demo_service.normal_rpc("demo")if__name__=='__main__':loop=asyncio.get_event_loop()loop.run_until_complete(run())Sanic WrapperimportsslfromsanicimportSanicfromsanic.responseimportjsonfromaio_pikaimportDeliveryModefromaio_nameko_proxy.wrappersimportSanicNamekoClusterRpcProxyclassConfig(object):# AMQP_URI: RequiredNAMEKO_AMQP_URI="pyamqp://guest:guest@127.0.0.1:5672"# rpc_exchangeNAMEKO_RPC_EXCHANGE="nameko-rpc"# pool_sizeNAMEKO_POOL_SIZE=60# initial_sizeNAMEKO_INITIAL_SIZE=60# time_outNAMEKO_TIME_OUT=30# con_time_outNAMEKO_CON_TIME_OUT=5# serializerNAMEKO_SERIALIZER="json"# ACCEPTNAMEKO_ACCEPT=["pickle","json"]# SERIALIZERS: custom serializersNAMEKO_SERIALIZERS={"my_serializer":{"encoder":"my_slizer.dumps","decoder":"my_slizer.loads","content_type":"my-content-type","content_encoding":"utf-8"}}# AMQP_SSL: ssl configsNAMEKO_AMQP_SSL={'ca_certs':'certs/ca_certificate.pem',# or 'cafile': 'certs/ca_certificate.pem','certfile':'certs/client_certificate.pem','keyfile':'certs/client_key.pem','cert_reqs':ssl.CERT_REQUIRED}# delivery_modeNAMEKO_DELIVERY_MODE=DeliveryMode.PERSISTENT# other supported properties of aio-pika.Message, the key name format is "NAMEKO_{}".format(property_name.upper())# ...app=Sanic("App Name")app.config.from_object(Config)# rpc_cluster = SanicNamekoClusterRpcProxy(app)# or# from aio_nameko_proxy.wrappers import rpc_cluster  # contextvars required in py36# SanicNamekoClusterRpcProxy(app)# orrpc_cluster=SanicNamekoClusterRpcProxy()rpc_cluster.init_app(app)@app.route("/")asyncdeftest(request):rpc=awaitrpc_cluster.get_proxy()result=awaitrpc.rpc_demo_service.normal_rpc("demo")reply_obj=awaitrpc.rpc_demo_service.normal_rpc.call_async("demo")result=awaitreply_obj.result()result=awaitrpc.rpc_demo_service.normal_rpc.sw_dlm_call("demo")reply_obj=awaitrpc.rpc_demo_service.normal_rpc.sw_dlm_call_async("demo")result=awaitreply_obj.result()returnjson({"hello":"world"})@app.websocket('/ws')asyncdefws(request,ws):rpc=awaitrpc_cluster.get_proxy()foriinrange(3):_=awaitws.recv()result=awaitrpc.rpc_demo_service.normal_rpc("demo")awaitws.send(result)ws.close()# in websocket handlers, you should call the remove actively in the endrpc_cluster.remove()if__name__=="__main__":app.run(host="0.0.0.0",port=8000)FastAPI WrapperimportsslfromfastapiimportFastAPI,WebSocketfromaio_pikaimportDeliveryModefrompydanticimportBaseSettingsfromaio_nameko_proxy.wrappersimportFastApiNamekoProxyMiddleware,rpc_cluster# contextvars required in py36classSettings(BaseSettings):# AMQP_URI: RequiredNAMEKO_AMQP_URI="pyamqp://guest:guest@127.0.0.1:5672"# rpc_exchangeNAMEKO_RPC_EXCHANGE="nameko-rpc"# pool_sizeNAMEKO_POOL_SIZE=60# initial_sizeNAMEKO_INITIAL_SIZE=60# time_outNAMEKO_TIME_OUT=30# con_time_outNAMEKO_CON_TIME_OUT=5# serializerNAMEKO_SERIALIZER="json"# ACCEPTNAMEKO_ACCEPT=["pickle","json"]# SERIALIZERS: custom serializersNAMEKO_SERIALIZERS={"my_serializer":{"encoder":"my_slizer.dumps","decoder":"my_slizer.loads","content_type":"my-content-type","content_encoding":"utf-8"}}# AMQP_SSL: ssl configsNAMEKO_AMQP_SSL={'ca_certs':'certs/ca_certificate.pem',# or 'cafile': 'certs/ca_certificate.pem','certfile':'certs/client_certificate.pem','keyfile':'certs/client_key.pem','cert_reqs':ssl.CERT_REQUIRED}# delivery_modeNAMEKO_DELIVERY_MODE=DeliveryMode.PERSISTENT# other supported properties of aio-pika.Message, the key name format is "NAMEKO_{}".format(property_name.upper())# ...settings=Settings()app=FastAPI()app.add_middleware(FastApiNamekoProxyMiddleware,config=settings)@app.get("/")asyncdeftest():rpc=awaitrpc_cluster.get_proxy()result=awaitrpc.rpc_demo_service.normal_rpc("demo")reply_obj=awaitrpc.rpc_demo_service.normal_rpc.call_async("demo")result=awaitreply_obj.result()result=awaitrpc.rpc_demo_service.normal_rpc.sw_dlm_call("demo")reply_obj=awaitrpc.rpc_demo_service.normal_rpc.sw_dlm_call_async("demo")result=awaitreply_obj.result()return{"hello":"world"}@app.websocket("/ws")asyncdefws(ws:WebSocket):awaitws.accept()rpc=awaitrpc_cluster.get_proxy()foriinrange(3):_=awaitws.receive()result=awaitrpc.rpc_demo_service.normal_rpc("demo")awaitws.send(result)ws.close()# in websocket handlers, you should call the remove() actively in the endrpc_cluster.remove()