Python:打印 protobuf 规范(字段、类型)

Python: print protobuf spec (fields, types)

如果你有一个对应于 module_name_pb2.py 文件的模块对象,或者访问 .proto 文件本身,有没有办法打印 spec 本身 一个漂亮的方式? JSON?我想显示字段和类型。

想要打印一个实例,例如

给定一些 protobuf 消息格式(在 .proto 文件中定义),例如:

message XYData {
    float x = 1;
    float y = 2;
}

我正在寻找类似的东西:

{
   "name" : "XYData",
   "fields" : [
                {"name" : "x", "type" : "float"},
                {"name" : "y", "type" : "float"}
              ]
}

如果能够列出 .proto 文件中定义的所有消息也很好。

编辑:可能是这样的,但在 Python 中:https://github.com/devongovett/protobuf-jsonschema

参见 Python 模块和示例 protobuf 定义 here

给定示例 protobuf 定义:

syntax = "proto3";

message Data1 {
    double a = 1;
    float b = 2;
    int32 c = 3;
    int64 d = 4;
    bool e = 5;
    string f = 6;
    bytes g = 7;
}

message Data2 {
    Data1 a = 1;
    map<string, Data1> b = 2;
    map<string, int32> c = 3;
    repeated Data1 d = 4;
    repeated int32 e = 5;
}

生成如下:

>>> import test_pb2
>>> msgs = module_msgs(test_pb2)
>>> print(msgs)

{'Data1': Data1(a='TYPE_DOUBLE', b='TYPE_FLOAT', c='TYPE_INT32', d='TYPE_INT64', e='TYPE_BOOL', f='TYPE_STRING', g='TYPE_BYTES'),
 'Data2': Data2(a=Data1(a='TYPE_DOUBLE', b='TYPE_FLOAT', c='TYPE_INT32', d='TYPE_INT64', e='TYPE_BOOL', f='TYPE_STRING', g='TYPE_BYTES'), b=Map(key='TYPE_STRING', value=Data1(a='TYPE_DOUBLE', b='TYPE_FLOAT', c='TYPE_INT32', d='TYPE_INT64', e='TYPE_BOOL', f='TYPE_STRING', g='TYPE_BYTES')), c=Map(key='TYPE_STRING', value='TYPE_INT32'), d=Repeated(value=Data1(a='TYPE_DOUBLE', b='TYPE_FLOAT', c='TYPE_INT32', d='TYPE_INT64', e='TYPE_BOOL', f='TYPE_STRING', g='TYPE_BYTES')), e=Repeated(value='TYPE_INT32')),
}

module_msgs 函数将一个 protobuf 模块作为输入,returns 一个 dict 以消息名称作为键,并生成 namedtuple 个对象作为值。这是要使用的 "top level" 函数。

我使用 nametuple 类型来表示 protobuf 消息。您可以通过 _fields 属性遍历它们的字段。事后看来,也许 typing.NamedTuplecollections.OrderedDict 会更合适。

我创建了两个特殊的 namedtupleMapRepeated。您可以通过 isinstance 检查确定一个字段是映射还是重复。

TYPE_* 字符串对应protobuf字段类型。因此,protobuf 消息 namedtuple 将具有字符串(对应于 protobuf 类型)、RepeatedMap 对象或另一个 namedtuple 对象的字段值。

这尚未与其他 protobuf 功能一起测试,例如默认值、Any、Oneof 等

有关更多用法和测试,请参阅要点中的 __main__