0

我正在尝试从可在此处找到的 containerd API .proto 文件生成工作 Python 模块:https ://github.com/containerd/containerd/tree/master/api 。

不幸的是,containerd 自己的 .proto 文件包含诸如 (in api/events/container.proto) 之类的引用:

import weak "github.com/containerd/containerd/protobuf/plugin/fieldpath.proto";

现在,这个导入实际上位于protobuf/plugin/fieldpath.proto,而不是 ( vendor/) github.com/containerd/...。简单-I ...在这种情况下不起作用,因为导入使用“github”-绝对路径,而相应的源不在供应商分支内。

vendor/github.com/...在尝试使用生成的 Python 模块时,简单地复制内部的源代码会导致运行时错误:这是因为现在有相同协议元素的两个单独实例尝试使用相同的协议元素名称向 GRPC 注册,但来自两个不同的 Python模块。因此,GRPC Python 运行时会引发错误并终止。

使用时如何正确解决此问题python3 -m grpc.tools.protoc ...

4

1 回答 1

1

经过反复试验,我终于想出了一个工作解决方案,其工作原理如下,这可能对其他面临基于 gRPC 的 API 的人有所帮助,这些 API 比许多 gRPC 示例更复杂。

  1. 将 API .proto 文件复制到反映最终所需 Python 包和模块结构的目录结构中。对于 containerd,这意味着将所有内容都放在 containerd/ 目录结构中,避免 github.com/ 文件夹和别名(导入别名会破坏事情)。
  2. 修复所有可能导致模块别名或不适合最终所需包结构的导入语句路径。一个很好的方法是在复制原始文件时使用 sed。就我而言,将“github.com/containerd/containerd/...”替换为“containerd/...”导入路径。
  3. 如果供应商的 .proto 文件以某种方式与 gRPC 基础设施相关并且存在 gRPC PyPI 包,例如 grpcio 和 protobuf,则将它们与您的 API .proto 文件并排放置,但不要将它们供应到 API 目录中等级制度。确保将它们放在一个模仿现有 PyPI 包的包结构的目录结构中。
  4. 通过 python3 解释器使用 protoc 为您的 API .proto 文件生成 Python 模块;确保来自 grpc 和 protobuf 的补充 .proto 文件是可包含的,但不要为它们创建模块。protoc 已经正确执行此操作,除非您将补充 .proto 文件供应到您的 API .proto 文件中......所以不要这样做。
  5. 确保您的 grpcio 和 protobuf PyPI 软件包是最新的并且以某种方式同步,避免特别完全过时的 Debian 发行版软件包,从 PyPI 安装......即使这是在 arm64 上的一个非常缓慢的过程,因为 grpcio 和 grpciotools 没有二进制轮. 不这样做的症状包括缺少 grpc 或 protobuf 对象字段的运行时错误。
于 2020-12-12T13:34:27.047 回答