有没有办法将数据直接从 python 请求流到 minio 存储桶

Jud*_*uch 5 python stream python-3.x python-requests minio

我正在尝试向服务器发出 GET 请求以检索 tiff 图像。然后我想使用 MinIO python SDK 中的 put_object 方法将它直接流式传输到 MinIO。

我知道我可以通过将图像保存到临时文件然后上传来做到这一点,但我想看看是否可以跳过这一步。

我试过直接插入字节响应并使用 BytesIO 来包装它,但我想我错过了一些东西。

r = requests.get(url_to_download, stream=True)
Minio_client.put_object("bucket_name", "stream_test.tiff", r.content, r.headers['Content-length'])
Run Code Online (Sandbox Code Playgroud)

我得到以下错误

AttributeError: 'bytes' 对象没有属性 'read'

任何帮助深表感谢!

Din*_*har 5

阅读有关 MinIO 的文档put_object,其中有如何将新对象添加到对象存储服务器的示例。这些示例仅说明如何添加文件。

这是put_object函数的定义:

put_object(bucket_name, object_name, data, length, content_type='application/octet-stream', metadata=None, progress=None, part_size=510241024)

我们对参数感兴趣data。它指出:

任何实现 io.RawIOBase 的 python 对象。

RawIOBase是原始二进制 I/O 的基类。它还定义了 method read

如果我们使用dir()内置函数来尝试返回 的有效属性列表r.content,那么我们可以检查是否read存在:

'read' in dir(r.content)-> 返回False

这就是你得到的原因AttributeError: 'bytes' object has no attribute 'read'。因为type(r.content)bytes班级啊


您可以转换r.content为继承自 的类RawIOBase。即使用io.BytesIO类。要获取对象的大小(以字节为单位),我们可以使用io.BytesIO(r.content).getbuffer().nbytes.

因此,如果您想将原始数据字节流式传输到存储桶,请将bytes类转换为io.BytesIO类:

import io
import requests

r = requests.get(url_to_download, stream=True)
raw_img = io.BytesIO(r.content)
raw_img_size = raw_img.getbuffer().nbytes

Minio_client.put_object("bucket_name", "stream_test.tiff", raw_img, raw_img_size)
Run Code Online (Sandbox Code Playgroud)

注意:示例显示从文件中读取二进制数据并通过读取使用函数返回的st_size属性来获取其大小。stat_resultos.stat()

st_size相当于io.BytesIO(r.content).getbuffer().nbytes.