我正在尝试向服务器发出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'])
我得到以下错误
AttributeError:“字节”对象没有属性“读取”
非常感谢您的帮助!
答案 0 :(得分:2)
您可以像这样直接将文件流式传输到minio存储桶中:
import requests
from pathlib import Path
from urllib.parse import urlparse
from django.conf import settings
from django.core.files.storage import default_storage
client = default_storage.client
object_name = Path(urlparse(response.url).path).name
bucket_name = settings.MINIO_STORAGE_MEDIA_BUCKET_NAME
with requests.get(url_to_download, stream=True) as r:
content_length = int(r.headers["Content-Length"])
result = client.put_object(bucket_name, object_name, r.raw, content_length)
或者您可以直接使用Django文件字段:
with requests.get(url_to_download, stream=True) as r:
# patch the stream to make django-minio-storage belief
# it's about to read from a legit file
r.raw.seek = lambda x: 0
r.raw.size = int(r.headers["Content-Length"])
model = MyModel()
model.file.save(object_name, r.raw, save=True)
Dinko Pehar的RawIOBase提示确实很有帮助,非常感谢。但是您必须使用response.raw而不是response.content,它会立即下载文件,并且在尝试存储大型视频时确实非常不便。
答案 1 :(得分:0)
在MinIO上阅读关于put_object
的{{3}},有一些示例如何将新对象添加到对象存储服务器。这些示例仅说明了如何添加文件。
这是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对象。
documentation是原始二进制I / O的基类。它还定义了方法read
。
如果我们要使用RawIOBase内置函数来尝试返回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)
注意:示例显示了从文件读取二进制数据并通过从st_size
读取stat_result
属性(通过使用os.stat()
函数返回)来获取其大小。 / p>
st_size
等同于io.BytesIO(r.content).getbuffer().nbytes
。