def _build_serializer_cls_for_proto_cls(proto_cls, for_dict=True, message_proto_map=None): serializer_name = f'{proto_cls.__name__}Serializer' attrs = dict(protobuf_class=proto_cls) fields_by_name = proto_cls.DESCRIPTOR.fields_by_name for name, field in fields_by_name.items(): if field.type == FieldDescriptor.TYPE_MESSAGE: serializer_field = None type_name = field.message_type.full_name if type_name == 'google.protobuf.Timestamp': serializer_field = fields.DateTimeField() elif type_name in VALUE_TYPES: serializer_field = fields.WrappedField() elif message_proto_map: is_repeated = field.label == FieldDescriptor.LABEL_REPEATED proto_cls = message_proto_map.get(type_name) if proto_cls: serializer = get_serializer_for_proto_cls( proto_cls, message_proto_map=message_proto_map) serializer_field = fields.Nested(serializer=serializer, many=is_repeated) else: # pragma: no cover logger.debug( 'Not sure what to do with %s, not in message_proto_map', name) else: # pragma: no cover logger.debug('Not sure what to do with %s', name) if serializer_field: attrs[name] = serializer_field else: serializer_field = fields.Field() attrs[name] = fields.Field() if for_dict: base_cls = ProtobufDictSerializer else: base_cls = ProtobufSerializer cls = type( serializer_name, (base_cls, ), attrs, ) return cls
class CoinSerializer(ProtobufSerializer): protobuf_class = Coin categories = fields.Nested(CategorySerializer, many=True)
class ParentSerializer(ProtobufSerializer): protobuf_class = Parent name = fields.Field() label = fields.WrappedField() child = fields.Nested(ChildSerializer)
class ChildSerializer(ProtobufSerializer): protobuf_class = Child name = fields.Field() label = fields.WrappedField() category = fields.Nested(CategorySerializer)