【问题标题】:python3 grpc compiler: how to handle absolute and relative imports in .protos?python3 grpc 编译器:如何处理.protos 中的绝对和相对导入?
【发布时间】:2020-12-12 21:34:27
【问题描述】:

我正在尝试从 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”-绝对路径,而相应的源不在供应商分支内。

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

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

【问题讨论】:

    标签: grpc-python containerd


    【解决方案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 对象字段的运行时错误。

    【讨论】:

      猜你喜欢
      • 2015-04-08
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 2012-09-23
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 2014-07-12
      相关资源
      最近更新 更多