ParseFromString无法解码消息

时间:2018-11-28 06:24:03

标签: python rest protocol-buffers

我正在尝试与一个RESTful API进行接口,该API在发布后接受application / x-protobuf对象。

.proto示例对象:

message register
{
    required string name = 1;
    required int32 id = 2;
}

使用请求,我可以将此消息发布到服务器并收到200。

例如

register = protobuf_pb2.register()
register.name = "foo"
register.id = 1

response = requests.request("POST", url, data=register.SerializeToString(), headers=headers)

当我以SerializeToString()格式查看此有效负载时,它显示类似于

  

b'\ n \ t \ n \ x03foo \ x10 \ x01'

作为健全性检查,我可以然后创建一个新的消息对象,并在其上将.ParseFromString()返回正确的消息格式。

服务器上的第二个uri允许您发送GET请求以检索相同的数据。因此,我使用了以下内容:

register = protobuf_pb2.register()
response = requests.request("GET", url, headers=headers).content
register.ParseFromString(response)

响应返回

  

b'foo:1 \ n'

ParseFromString返回异常

  

DecodeError('错误解析消息',)

我在某处错过了一步吗? .content有效内容在解析之前是否应该进行某种编码?

非常感谢。

1 个答案:

答案 0 :(得分:0)

您从服务器取回的对象是二进制数据,采用UTF-8编码,因此Python将其解释为bytes对象(在Python 3中,bytesstr是不同类型)。

m = b'foo:1\n'
type(m)
Out[1]: bytes

m.decode('utf-8')
Out[2]: 'foo:1\n'

ParseFromString但是需要一个字符串,因此会抛出一个DecodeError;只需使用带有适当编码的decode()

在响应标头中,您应该能够找到所使用的编码:几乎每个人都使用UTF-8,但是在“真实”生产代码中,您也应该进行检查:在Content-Type中(或者您可以甚至用Accept-Charset请求一个特定的服务器,但如果服务器无法完成,则可能会得到406)。