How can a nested Protobuf Struct be parsed to a Python dict?

Viewed 127

Single level Protobuf Struct fields can be parsed to Python dicts by passing the Struct to the Python dict. However, this does not work with nested dicts. Is there an officially supported method to convert nested Protobuf structs to dicts?

from google.protobuf.struct_pb2 import Struct

simple_struct = Struct()
simple_struct.update({"hi": 1, "there": 2})
print(dict(simple_struct))

nested_struct = Struct()
nested_struct.update({"hi": 1, "over": {"there": 23}})
print(dict(nested_struct))
# Output
{'there': 2.0, 'hi': 1.0}
{'hi': 1.0, 'over': fields {
  key: "there"
  value {
    number_value: 23.0
  }
}
}
1 Answers

I could not find any supported method, but it is possible to recursively parse Protobuf Structs and return a proper Python dict that way.

from typing import Dict
from google.protobuf.struct_pb2 import Struct

def struct_to_dict(struct: Struct, out: Dict = None) -> Dict:
    if not out:
        out = {}
    for key, value in struct.items():
        if isinstance(value, Struct):
            out[key] = struct_to_dict(value)
        else:
            out[key] = value
    return out

struct = Struct()
struct.update({"hi": 1, "over": {"there": 23}})
out = struct_to_dict(struct)

print("bad:")
print(dict(struct))

print("good:")
print(out)
# Output
bad:
{'hi': 1.0, 'over': fields {
  key: "there"
  value {
    number_value: 23.0
  }
}
}
good:
{'hi': 1.0, 'over': {'there': 23.0}}
Related