如何使用requests.post发送BytesIO

3

我正在尝试使用requests post向一个插入rest端点发送经过msgpack编码的值,该端点将序列化的字节流作为输入。但似乎这些值没有正确到达,因为我发现没有任何值插入到表中。我以前从未尝试过这样做,所以请原谅我的无知。以下是我的操作:

buf = io.BytesIO()
for rows in dataframe:
    buf.write(msgpack.packb(rows))
    response = requests.post(url, data=buf, verify=False)
    try:
        response.raise_for_status()
    except requests.exceptions.HTTPError as err:
        print('Error fetching response using requests')

如果我没记错的话,数据需要是可迭代的才能被requests.post流式传输。你可能需要编写一个生成器函数将数据写入buf,并将该生成器传递给requests.post。在这种情况下,buf甚至可能不需要。 - DevLounge
buf.seek(0) 是将 buf 指针指向缓冲区末尾的方法。我还发现,我必须对每个值进行序列化,而不是字典列表,这就是插入失败的原因。 - ShellZero
3个回答

3
延伸您的回答,建议使用with语句块,以便在出现异常时修复内存泄漏问题。
for rows in dataframe:
    with io.BytesIO(msgpack.packb(rows)) as buf:
        buf.seek(0)
        response = requests.post(url, data=buf, verify=False)
    try:
        response.raise_for_status()
    except requests.exceptions.HTTPError as err:
        print('Error fetching response using requests')

1
很酷 :) 我喜欢这个。但在这种情况下我们还需要进行查找吗? - ShellZero

2
每当我向缓冲区写入时,指针总是指向缓冲区的末尾并等待新的写入。因此,当我传递data=buf时,这将进行一个没有值的插入操作。解决方案是执行buf.seek(0),然后将data=buf作为参数传递,或者简单地使用data=buf.seek(0)
因此,以下内容可以正常工作:
for rows in dataframe:
    buf = io.BytesIO()
    buf.write(msgpack.packb(rows))
    buf.seek(0)
    response = requests.post(url, data=buf, verify=False)
    try:
        response.raise_for_status()
    except requests.exceptions.HTTPError as err:
        print('Error fetching response using requests')

1
您可以在创建BytesIO对象时添加初始数据,这样您就不必调用seek
>>> import io
>>> buf = io.BytesIO(b"test")
>>> buf.tell()
0
>>> buf.read()
b'test'
>>> buf.tell()
4

啊,我明白了 :) 所以,我可以直接做 data=buf 对吧 :) - ShellZero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接