通过服务名称 远程调用服务

import os
import sys
import grpc


class CustomModule:
    def __init__(self, name, server_info, proto_files,):
        # proto_file: one folder,  includes  proto file name + proto file content
        self.name = name
        self.server_info = server_info
        self.proto_files = proto_files

    def register(self):
        bin_path = os.path.join("services", os.path.dirname(self.proto_files[0]['name']))
        proto_path = os.path.join("services", "protos", os.path.dirname(self.proto_files[0]['name']))

        if not os.path.exists(proto_path) :
            os.makedirs(proto_path)
        if not os.path.exists(bin_path):
            os.makedirs(bin_path)

        for file in self.proto_files:
            proto_file = os.path.join(proto_path, os.path.basename(file['name']))
            with open(proto_file, 'wb') as fw:
                fw.write(file['content'])
                
        # Run shell command
        command = f'python -m grpc_tools.protoc -I {proto_path} --python_out={bin_path} --grpc_python_out={bin_path} {proto_path}/*.proto'
        os.system(command)

    # def get_package(self):
    #     package = []
    #     for file in os.listdir(os.path.join('services', os.path.dirname(self.proto_files[0]['name']))):
    #         filename, ext = os.path.splitext(file)
    #         package.append(filename)
    #     return package

    def check_param_type(self, param_type_str):
        sys.path.append(
            os.path.join(os.path.dirname(__file__), 'services', os.path.dirname(self.proto_files[0]['name'])))
        for file in os.listdir(os.path.join('services', os.path.dirname(self.proto_files[0]['name']))):
            filename, ext = os.path.splitext(file)
            type_class = None
            type_matches = False
            try:
                package = __import__(filename)
                type_class = getattr(package, param_type_str)
                type_matches = True
                break
            except Exception as ex:
                continue
        if not type_matches:
            print(f"No type matches for type: {param_type_str}")
            exit(-1)
        return type_class


    def run(self,  run_service, run_method, input_param_type, input_param_value, response_type):
        # print(f"Execute node : {self.name}")
        input_class = self.check_param_type(input_param_type)
        response_class = self.check_param_type(response_type)

        input_instance = input_class()
        input_instance.ParseFromString(input_param_value)

        restful_api = f"/{run_service}/{run_method}"
        with grpc.insecure_channel(self.server_info) as channel:
            func = channel.unary_unary(
                restful_api,
                request_serializer = getattr(input_class, 'SerializeToString' ),
                response_deserializer=getattr(response_class, 'FromString' ),
                # request_serializer=pb_event.User.SerializeToString,
                # response_deserializer=pb_event.FileSet.FromString,
            )
            response = func(input_instance)
        print(response)


if __name__ == "__main__":
    model = CustomModule('test_journal','localhost:50052', [{'name': 'journal/journal_data.proto', 'content': open('/home/lc/PycharmProjects/python/my_travel/ai_learning/protos/journal_data.proto', 'rb').read()},
                                             {'name': 'journal/journal_event.proto', 'content': open('/home/lc/PycharmProjects/python/my_travel/ai_learning/protos/journal_event.proto', 'rb').read()}])
    model.register()
    # print(model.get_package())
    # print(model.check_param_type('User'))
    # print(model.check_param_type('FileSet'))

    curpath = os.path.dirname(__file__)
    sys.path.append(os.path.join(curpath, 'services', 'journal'))
    import journal_event_pb2 as pb_event

    user = pb_event.User(username='lc-host')
    model.run(run_service='JournalEvents', run_method='GetFileMetas', input_param_type='User', input_param_value=user.SerializeToString(), response_type='FileSet')

1. 首先在页面通过注册要调用的服务, 包含地址:接口,服务名称,以及相应的proto files (主要是为了得到传输过程中的数据类型)

2. 注册时会将proto file读入本地,然后调用 proto generation 生成 pb文件 

3. 注册模块之后就可以使用这个service下的所有方法,方法通过名字传入,输入参数的类型通过法序列化得到;

4.执行的时候就是调用grpc channel stub 执行相应的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值