I want to create a response message in grpc with the following format:
message Match {
int32 index = 1;
google.protobuf.Struct match = 2;
google.protobuf.Struct status = 3;
}
I have a serializer and I want to convert the data into protobuf struct. my serializer is nested and long, so i have posted only a small part of the code in here.
class MatchSerializer(proto_serializers.ModelProtoSerializer):
competition = serializers.SerializerMethodField()
match = serializers.SerializerMethodField()
status = serializers.SerializerMethodField()
class Meta:
model = Match
proto_class = base_pb2.Match
fields = ['index', 'match', 'competition', 'status']
def get_competition(self, obj):
data = SomeSerializer(obj.competition).data
struct_data = struct_pb2.Struct()
return struct_data.update(data)
def get_status(self, obj):
status_dict = {
0: {0: "not started"},
1: {1: "finished"},
2: {9: "live"},
}
result = status_dict[obj.status]
struct_data = struct_pb2.Struct()
return struct_data.update(result)
def get_match(self, obj):
data = SomeOtherSerializer(obj.match).data
struct_data = struct_pb2.Struct()
return struct_data.update(data)
Besides, I cannot find the source of what is really making this problem. I am getting this error from serializing:
Traceback (most recent call last):
File "/project/venv/lib/python3.10/site-packages/grpc/_server.py", line 555, in _call_behavior
response_or_iterator = behavior(argument, context)
File "/project/base/grpc/services.py", line 44, in GetUserSubscribedTeamsMatches
return MatchSerializer(val).message
File "/project/venv/lib/python3.10/site-packages/django_grpc_framework/proto_serializers.py", line 31, in message
self._message = self.data_to_message(self.data)
File "/project/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 555, in data
ret = super().data
File "/project/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "/project/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/project/venv/lib/python3.10/site-packages/rest_framework/fields.py", line 1838, in to_representation
return method(value)
File "/project/base/grpc/serializers.py", line 97, in get_matches
return struct_data.update(data[0])
File "/project/venv/lib/python3.10/site-packages/google/protobuf/internal/well_known_types.py", line 522, in update
_SetStructValue(self.fields[key], value)
File "/project/venv/lib/python3.10/site-packages/google/protobuf/internal/well_known_types.py", line 448, in _SetStructValue
struct_value.struct_value.update(value)
File "/project/venv/lib/python3.10/site-packages/google/protobuf/internal/well_known_types.py", line 522, in update
_SetStructValue(self.fields[key], value)
TypeError: bad argument type for built-in operation
I have tried debugging tools in pycharm and gone through some lines, but I do not seem to find the problem
While e.g. 0
(int
) is a valid key for a Python dict:
d = {
0: {0: "not started"},
1: {1: "finished"},
2: {9: "live"},
}
print(d)
It is not a valid Struct
key nor a valid JSON (object) key which Struct
is designed to represent:
match = Struct()
match.update(d)
Throws bad argument type for built-in operation
You will need to use string
values for keys:
map<string, Value>