协议缓冲区导入解析

时间:2017-09-09 13:07:08

标签: python protocol-buffers protoc

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

Proto Packages and Name Resolution州的文档

  

您可以通过导入来使用其他.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

enter image description here

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

  1. example.proto
  2. google/api/annotations.proto
  3. google/api/http.proto
  4. ......或作为一棵树:

    |____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 - 自annotations.proto起所需的protoc二进制文件附带的常见原型的位置取决于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 - 自annotations.proto起所需的protoc二进制文件附带的常见原型的位置取决于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.protohttp.proto中寻找google/api

    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.
    

    http.proto取决于哪个annotations.proto可以解决?

2 个答案:

答案 0 :(得分:0)

因为我正在尝试和你一样,我想出了一个可能的解决方案,使用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

答案 1 :(得分:0)

请尝试:pip install googleapis-common-protos。 我遇到了相同的错误,并使用此方法解决了该问题。