Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a prototbuf map in Python?

Given a proto definition

message EndpointResult {
    int32 endpoint_id = 1;
    // property id as key
    map<int32, TimeSeries> properties = 2;
}

message TimeSeries {
    repeated TimeEntry value = 2;
}

message TimeEntry {
    int32 time_unit = 1;
    float value = 2;
}

I wish to populate the map in the EndpointResult class. I have tried different approaches suggested in the docs but all raise a error for me.

Setting up a test class

end_point_rslt = nom.EndpointResult()
end_point_rslt.endpoint_id=0

ts = nom.TimeSeries()
te = ts.value.add()
te.time_unit = 0
te.value = 5.

Then trying the different approaches:

end_point_rslt.properties[0] = ts

ValueError: Direct assignment of submessage not allowed

end_point_rslt.properties[0].submessage_field = ts

AttributeError: Assignment not allowed (no field "submessage_field" in protocol message object).

end_point_rslt.properties.get_or_create(0)
end_point_rslt.properties[0] = ts

ValueError: Direct assignment of submessage not allowed

end_point_rslt.properties.get_or_create(0)
end_point_rslt.properties[0].submessage_field = ts

AttributeError: Assignment not allowed (no field "submessage_field" in protocol message object).

end_point_rslt.properties = {0 : ts}

AttributeError: Assignment not allowed to repeated field "properties" in protocol message object.

end_point_rslt.properties.get_or_create(0)
end_point_rslt.properties = {0 : ts}

TypeError: Can't set composite field

Any example of how to use a protocol buffer map in python would be greatly appreciate!

like image 936
Edgar H Avatar asked Nov 28 '18 12:11

Edgar H


People also ask

Does Protobuf support map?

According to Google protobuf doc, proto 2 does support map type https://developers.google.com/protocol-buffers/docs/proto#maps . As I quote, Maps cannot be repeated, optional, or required.

How do I read a proto file in Python?

import sys import myprotocol_pb2 as proto import varint # (this is the varint.py file) data = open("filename. bin", "rb"). read() # read file as string decoder = varint. decodeVarint32 # get a varint32 decoder # others are available in varint.py next_pos, pos = 0, 0 while pos < len(data): msg = proto.

What is Protobuf in Python?

Protocol buffers (Protobuf) are a language-agnostic data serialization format developed by Google. Protobuf is great for the following reasons: Low data volume: Protobuf makes use of a binary format, which is more compact than other formats such as JSON. Persistence: Protobuf serialization is backward-compatible.


1 Answers

After staring at the docs, I realized that the problem was me assigning a class to the dictionary.

The correct syntax is

end_point_rslt = nom.EndpointResult()
end_point_rslt.endpoint_id=0
te = end_point_rslt.properties[0].value.add()
te.time_unit = 0
te.value = 5.
like image 136
Edgar H Avatar answered Sep 20 '22 04:09

Edgar H