HiveNetGRpc.proto.proto_generate 源代码

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# Copyright 2022 黎慧剑
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""
proto生成工具模块

@module proto_generate
@file proto_generate.py
"""
import os
import sys
# 根据当前文件路径将包路径纳入, 在非安装的情况下可以引用到
sys.path.append(os.path.abspath(os.path.join(
    os.path.dirname(__file__), os.path.pardir, os.path.pardir)))
from HiveNetCore.utils.run_tool import RunTool
from HiveNetCore.utils.file_tool import FileTool


[文档]class ProtoTools(object): """ 处理Proto文件的工具类 """ ############################# # 静态工具类 #############################
[文档] @classmethod def generate_python_proto(cls, proto: str, output: str = None, add_hivenet_ref: bool = False, python_cmd: str = 'python'): """ 生成python的proto适配文件 @param {str} proto - 原始proto文件 @param {str} output=None - 要输出的目录, 如果为None代表在原始文件相同目录下 @param {bool} add_hivenet_ref=False - 是否在pb2_grpc添加HiveNet的引用代码 @param {str} python_cmd='python' - python的命令, 根据环境传入, 例如修改为python3 """ _proto = os.path.abspath(proto) if not os.path.exists(_proto): raise FileNotFoundError('proto file not found') # 输出目录和文件名 _proto_path, _filename = os.path.split(_proto) if output is not None: _output = os.path.abspath(output) else: _output = _proto_path if not os.path.exists(_output): FileTool.create_dir(_output, exist_ok=True) # 将当前目录切换到输出目录中, 执行编译命令 _cmd = '%s -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. --proto_path="%s" %s' % ( python_cmd, _proto_path, _filename ) os.chdir(_output) _cmd_ret = RunTool.exec_sys_cmd(_cmd) if _cmd_ret[0] != 0: print(_cmd_ret[1]) # 打印 raise RuntimeError('execute cmd error: %s' % _cmd) if add_hivenet_ref: # 修改pb2_grpc文件 _pb2_name = '%s_pb2' % _filename[0: -6] _pb2_grpc_name = '%s_grpc.py' % _pb2_name _start_code = [ 'import sys', 'import os', 'sys.path.append(os.path.abspath(os.path.join(', ' os.path.dirname(__file__), os.path.pardir, os.path.pardir)))', '' ] with open(_pb2_grpc_name, 'r', encoding='utf-8') as _f: _new_code_str = '%s\r\n%s' % ( '\r\n'.join(_start_code), _f.read().replace( 'import %s as %s' % ( _pb2_name, _pb2_name.replace('_', '__') ), 'import HiveNetGRpc.proto.%s as %s' % ( _pb2_name, _pb2_name.replace('_', '__') ) ) ) with open(_pb2_grpc_name, 'w', encoding='utf-8') as _f: _f.write(_new_code_str)
[文档] @classmethod def generate_python_proto_by_path(cls, path: str, output: str = None, add_hivenet_ref: bool = False, python_cmd: str = 'python'): """ 把目录里的所有proto文件生成python适配文件 @param {str} path - 要处理的目录 @param {str} output=None - 要输出的目录, 如果为None代表在原始文件相同目录下 @param {bool} add_hivenet_ref=False - 是否在pb2_grpc添加HiveNet的引用代码 @param {str} python_cmd='python' - python的命令, 根据环境传入, 例如修改为python3 """ _file_list = FileTool.get_filelist(path=path, regex_str=r'.*\.proto$') for _file in _file_list: cls.generate_python_proto( _file, output=output, add_hivenet_ref=add_hivenet_ref, python_cmd=python_cmd )
if __name__ == '__main__': # 运行命令生成当前目录的适配器 _path = os.path.abspath(os.path.join( os.path.dirname(__file__) )) ProtoTools.generate_python_proto_by_path(_path, add_hivenet_ref=True)