【问题标题】:ParseFromString failure to decode messageParseFromString 无法解码消息
【发布时间】:2019-04-17 12:52:08
【问题描述】:

我正在尝试与一个 RESTful API 交互,该 API 在 post 中接受 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 有效载荷是否应该在解析之前以某种方式编码?

非常感谢。

【问题讨论】:

    标签: python rest protocol-buffers


    【解决方案1】:

    您从服务器返回的对象是二进制数据,采用 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)。

    【讨论】:

      猜你喜欢
      • 2016-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      • 1970-01-01
      • 2016-03-18
      • 2015-11-07
      • 1970-01-01
      相关资源
      最近更新 更多