python - Protocol Buffer导入解析

标签 python protocol-buffers protoc

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

Proto 文档 Packages and Name Resolution

You can use definitions from other .proto files by importing them. To import another .proto's definitions, you add an import statement to the top of your file.

我的 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 - 他们是同一个包中的 sibling (googleapis/google/api)

enter image description here

我的本​​地项目目录包含三个 .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

有了这个我就可以编译我的原型(prototype)了(添加格式以提高可读性):

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 二进制文件附带的通用 proto 的位置,自 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 二进制文件附带的通用 proto 的位置,自 annotations.proto 起需要取决于 google/protobuf/descriptor.proto .
  • google/api - annotations.proto 所依赖的 http.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

最佳答案

因为我正在尝试与您做同样的事情,所以我想出了一个可能的解决方案,使用 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 生成项目特定的协议(protocol)

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

关于python - Protocol Buffer导入解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46131022/

相关文章:

Python Flask 应用程序在本地运行,但在 Heroku 上托管时返回 AttributeError

python - 如何在 Python 中获取函数的调用表达式?

java - 用于 Protobuf 编译器的 gRPC Java Codegen 插件

go - protoc 生成值而不是指针(Go)

python - __enter__ 和 __exit__ 在 python 3 中的类级别

python - 在 protobuf python api 中,如何将元素添加到嵌套消息的重复属性中?

linux - 如何在 unix 中使用 protobuf-csharp-port

android - 未找到 protoc-gen-javanano

go - 使用protoc生成golang代码时导入和使用其他.proto文件出错

Python 获取控制台输出