Python: print protobuf spec (fields, types)

If you have a module object corresponding to a module_name_pb2.py file, or access to the .proto file itself, is there a way to print the spec itself in a pretty way? JSON? I want to show the fields and the types.

I am not looking to print an instance eg, Print human friendly Protobuf message

Given some protobuf message format (Defined in a .proto file) like:

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

I am looking for something like:

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

It would also be nice to be able to list all the messages defined in the .proto file.

EDIT: maybe something like this but in Python: https://github.com/devongovett/protobuf-jsonschema


See the Python module and example protobuf definition here

Given the example protobuf definition:

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;
}

The following is produced:

>>> 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')),
}

The module_msgs function takes a protobuf module as input and returns a dict with message names as keys, and generated namedtuple objects as values. This is the "top level" function to use.

I used nametuple types to represent protobuf messages. You can iterate over their fields via the _fields attribute. In hindsight, perhaps typing.NamedTuple or collections.OrderedDict would have been more appropriate.

I created two special namedtuple s: Map and Repeated . You can determine if a field is a map or repeated with isinstance checks.

The TYPE_* strings correspond to protobuf field types. Thus a protobuf message namedtuple will have field values that are either strings (corresponding to a protobuf type), a Repeated or Map object, or another namedtuple object.

This has not been tested with other protobuf features, such as default values, Any, Oneof, etc.

See __main__ in the gist for more usage and tests.

链接地址: http://www.djcxy.com/p/77290.html

上一篇: Google Protobuf空字段和消息标准(Python)

下一篇: Python:打印protobuf规范(字段,类型)