【问题标题】:Protocol Buffer import resolutionProtocol Buffer 导入解析
【发布时间】:2023-03-16 23:54:02
【问题描述】:

在阅读这个相当长的问题之前,我提出了一个错误https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1103

Proto Packages and Name Resolution states 的文档

您可以通过导入来自其他 .proto 文件的定义来使用它们。到 导入另一个 .proto 的定义,你添加一个 import 语句到 文件的顶部。

我的example.proto 依赖于annotations.prototranscode HTTP/JSON to gRPC。这是一个简单的示例,但请注意我使用来自 googleapis/google/api Git 存储库的导入路径(即 google/api/annotations.proto):

syntax = "proto3";
import "google/api/annotations.proto";

message MyExample {
  // Message definition here.
}

注意,annotations.proto 依赖于 http.proto - 它们是同一个包中的兄弟 (googleapis/google/api)

我的本​​地项目目录包含三个 .proto 文件:

  1. example.proto
  2. google/api/annotations.proto
  3. google/api/http.proto

...或作为一棵树:

|____google
| |____api
| | |____annotations.proto
| | |____http.proto
|____example.proto

目标(或'out')目录也被添加,准备接收生成的python文件:

|____generated_pb2
| |____google
| | |____api

我完整的项目目录结构是:

  • example.proto
  • google/api/annotations.proto
  • google/api/http.proto
  • generated_pb2/google/api

...或作为一棵树:

|____example.proto
|____google
| |____api
| | |____annotations.proto
| | |____http.proto
|____generated_pb2
| |____google
| | |____api

有了这个,我可以编译我的原型(为可读性添加了格式):

python -m grpc_tools.protoc
  --python_out=generated_pb2
  --grpc_python_out=generated_pb2
  -I ~/protoc/include/google/protobuf
  -I /google/api
  example.proto

分解:

  • generated_pb2 - 生成的 python 文件和 gprc 文件的目的地。
  • ~/protoc/include/google/protobuf - 随 protoc 二进制文件一起提供的通用 protos 的位置,因为 annotations.proto 取决于 google/protobuf/descriptor.proto,所以需要它。
  • google/api - annotations.protohttp.proto 的位置

这编译example.proto给:

  • generated_pb2/example_pb2.py
  • generated_pb2/example_pb2_gprc.py

但是generated_pb2/example_pb2.py 的第一行会导入为annotations.proto 生成的文件:

from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2

此文件不存在。没问题,我单独编译annotations.proto

python -m grpc_tools.protoc
  --python_out=generated_pb2/google/api
  --grpc_python_out=generated_pb2/google/api
  -I ~/protoc/include/google/protobuf
  -I google/api annotations.proto

分解:

  • generated_pb2/google/api - 生成的 python 文件和 gprc 文件的目的地。
  • ~/protoc/include/google/protobuf - 与 protoc 二进制文件一起提供的通用 protos 的位置,因为 annotations.proto 取决于 google/protobuf/descriptor.proto,所以需要。
  • google/api - http.proto 的位置,annotations.proto 所依赖的位置。

很遗憾,此时我遇到了错误:

google/api/http.proto: File not found.
annotations.proto: Import "google/api/http.proto" was not found or had errors.
annotations.proto:30:3: "HttpRule" is not defined.

我猜这是因为annotations.protogoogle/api 中寻找http.proto

syntax = "proto3";
package google.api;

import "google/api/http.proto";
import "google/protobuf/descriptor.proto";

但目前尚不清楚如何解决这种依赖关系。 protoc --help 记录 -I 标志:

-IPATH, --proto_path=PATH   Specify the directory in which to search for
                            imports.  May be specified multiple times;
                            directories will be searched in order.  If not
                            given, the current working directory is used.

annotations.proto 所依赖的http.proto 如何解决?

【问题讨论】:

  • 您的“导入”中的东西只是由所有 -I 路径依次组成,直到找到匹配项(正好一个)。真的就这么简单。然后它继续 - 所以如果他们“进口”,同样的事情会再次发生。根据记忆,它与单个 .proto 无关 - 它与 -I 参数有关。
  • @marc-gravell - 它似乎是相对的。我已经更新了我的问题,解释了我为什么这么认为,但简要说明:google/api/http.proto 包含在google/api/annotations.proto 中时无法找到

标签: python protocol-buffers protoc


【解决方案1】:

当我尝试和你做同样的事情时,我想出了一个可能的解决方案,使用 Makefile 创建适当的文件。 因为我是用python测试的,所以我安装了grpc python包并通过python使用protoc而不是直接使用它,但是输入和结果应该是一样的。

每个 protoc 调用中使用的通用 protobuf 标志:

GRPC_FLAGS := \
    -I. \
    -I/usr/local/include \
    -I$(GOPATH)/src \
    -I$(GOPATH)/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis

源代码生成

源代码特定标志:

CLIENT_FLAGS := \
    --proto_path=./protos \       <-- This is where my *.proto live
    --python_out=grpctest/client \
    --grpc_python_out=grpctest/client

调用 protoc 以从您的 *.proto 生成项目特定协议

python3 -m grpc_tools.protoc $(CLIENT_FLAGS) $(GRPC_FLAGS) protos/*.proto

注释生成

注解特定标志:

CLIENT_GW_FLAGS := \
    --python_out=grpctest/client \
    --grpc_python_out=grpctest/client

调用 protoc 生成注解特定文件:

python3 -m grpc_tools.protoc $(CLIENT_GW_FLAGS) $(GRPC_FLAGS) google/api/annotations.proto
python3 -m grpc_tools.protoc $(CLIENT_GW_FLAGS) $(GRPC_FLAGS) google/api/http.proto

最终文件系统结构

├── client.py
├── config.yml
├── file
├── google
│   └── api
│       ├── __pycache__
│       ├── annotations_pb2.py
│       ├── annotations_pb2_grpc.py
│       ├── http_pb2.py
│       └── http_pb2_grpc.py
├── grpctest_pb2.py
└── grpctest_pb2_grpc.py

【讨论】:

  • 您好,这对我生成文件很有用。但是我的转码 grpc 网关的 REST 端点不工作。知道为什么吗?
【解决方案2】:

试试这个:pip install googleapis-common-protos。 我遇到了同样的错误,用这个方法解决了。

【讨论】:

    猜你喜欢
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多