Michael Amiethyst
Michael Amiethyst

Reputation: 187

How to modify a Protocol-Buffers ScalarMapContainer in Python?

I've been trying to add values to a ScalarMapContainer in Python. This object was autogenerated by Google's Protobuf3 library from the .proto:

map<string, string> mapName = 4;

According to the scant docs I found the ScalarMapContainer should act basically like a normal dict but doesn't.

I've tried accessing it like a normal dict. I deep copied it then called MergeFrom on the copy. I also created a new ScalarMapConatiner then called MergeFrom on it.

# normal dict
x.mapName["key"] = "value"
from google.protobuf.json_format import MessageToJson 
print(MessageToJson(x)) # key/value not present

# deep copy
copy = deepcopy(x.mapName)
copy["key"] = "value"
x.mapName.MergeFrom(copy)
print(MessageToJson(x)) # key/value not present

# new object
myMap = ScalarMapContainer()
myMap["key"] = "value"
x.mapName.MergeFrom(myMap) # crashes

I'm not sure what else to try to get this working.

Thank you.

Upvotes: 2

Views: 3380

Answers (1)

luizbarcelos
luizbarcelos

Reputation: 696

Say I have a protobuffer message as:

[...]
message ResponseMap {
    map<string, int32> pairs = 1;
}
[...]

and build my entire proto using grpc_tools.protoc.

The server-side could fill the message as if it was a dict. Example:

def get_map(self, request, context):
    result = gen_pb2.ResponseMap()
    # Fill in the map
    result.pairs['a'] = 2
    result.pairs['b'] = 3
    return result

The client-side, on the other hand, could read the key-value pairs as:

response = stub.get_map([...])
for k, v in response.pairs.items():
    print(f'{k}: {v}')

items method would let you iterate over the key-value pairs as if it was a dict.

In this simple example, pairs is a ScalarMapContainer.

Upvotes: 4

Related Questions