6

我们在 repo 中有一些 gRPC 的 proto 文件,我读到提交生成的代码并不好。所以我想我需要将生成作为包安装的一部分(例如 setuptools、setup.py)

但是,要生成 gRPC 代码,您需要先pip install grpcio-tools按照文档运行安装包。但是 setup.py 的目的是自动拉下像grpcio-tools这样的依赖项。

那么是否有这样做的最佳实践?如,如何从 setuptools 中生成依赖于另一个 python 包的代码?我最好创建一个单独的build.sh脚本来手动安装并生成代码吗?还是我应该期望该软件包的用户已经安装了grpcio-tools

4

2 回答 2

9

据我所知,“当前”的最佳做法是:

  • pip 管理依赖
  • setup.py 执行构建

执行“点安装”。几乎等同于执行“pip install -r requirements.txt”+“python setup.py build”+“python setup.py install”。

这是一个从 proto 文件生成 python 源的自定义命令:

class GrpcTool (Command):
    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        import grpc_tools.protoc

        proto_include = pkg_resources.resource_filename('grpc_tools', '_proto')

        grpc_tools.protoc.main([
            'grpc_tools.protoc',
            '-I{}'.format(proto_include),
            '--python_out=SOME_PATH/',
            '--grpc_python_out=SOME_PATH/',
            'SOME_PROTO.proto'
        ])

调用自定义 build_py 命令,如下所示:

class BuildPyCommand (build_py):
    def run(self):
        self.run_command('grpc')
        super(BuildPyCommand, self).run()

注意run 方法的导入。似乎 pip 在安装要求之前和之后运行了 setup.py 几次。因此,如果您在文件顶部进行了导入,则构建将失败。

于 2019-01-17T13:13:11.570 回答
1

除了@makeroo 方法,另一种方法是将grpc_tools模块作为子进程执行。

这种方法的好处是肯定会收到生成结果;0是成功和1错误。

proto_files = ["proto/file1.proto", "proto/file2.proto"]

import subprocess
for file in proto_files:
    args = "--proto_path=. --python_out=. --grpc_python_out=. {0}".format(file)
    result = subprocess.call("python -m grpc_tools.protoc " + args, shell=True)
    print("grpc generation result for '{0}': code {1}".format(file, result))

上面的代码将创建生成的 python 文件到文件所在的proto目录.proto

于 2019-11-23T07:27:54.530 回答