我正在尝试与一个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有效内容在解析之前是否应该进行某种编码?
非常感谢。
答案 0 :(得分:0)
您从服务器取回的对象是二进制数据,采用UTF-8编码,因此Python将其解释为bytes
对象(在Python 3中,bytes
和str
是不同类型)。
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)。