将matplotlib图像存储在boto3 1.5.36上的s3.Object().put()



除其他我正在使用 matplotlib绘制的图,我想立即将其存储为S3对象。

根据此问题和其他问题和精细手册中提供的答案,我需要S3.Object.put()将数据移至AWS中,并且该过程应沿着

的行为
from matplotlib import pyplot as plt
import numpy as np
import boto3
import io
# plot something
fig, ax = plt.subplots()
x = np.linspace(0, 3*np.pi, 500)
a = ax.plot(x, np.sin(x**2))
# get image data, cf. https://stackoverflow.com/a/45099838/1129682
buf = io.BytesIO()
fig.savefig(buf, format="png")
buf.seek(0)
image = buf.read()
# put the image into S3
s3 = boto3.resource('s3', aws_access_key_id=awskey, aws_secret_access_key=awssecret)
s3.Object(mybucket, mykey).put(ACL='public-read', Body=image)

但是,我最终得到了一个新的S3对象,其长度为零。

以下给我一个带有内容长度6的新的S3对象。

s3.Object(mybucket, mykey).put(ACL='public-read', Body="foobar")

当我放下下一行时,我最终在S3对象中得到了内容,但它不是可用的图像:

s3.Object(mybucket, mykey).put(ACL='public-read', Body=str(image))

我可以通过浏览实际文件来使其正常工作:

with open("/tmp/iamstupid","wb") as fh:
    fig.savefile(fh, format="png")
s3.Bucket(mybucket).upload_file("/tmp/iamstupid", mykey)

所以它似乎可以工作。我只是无法正确使用该接口。我究竟做错了什么?如何使用S3.Object.put()

实现目标

我能够解决它。我在这个问题中找到了答案。它是Python3的东西。据我了解,python3"通常"与Unicode一起使用。如果您想要单个字节,则必须对此明确。因此,正确的用法是

s3.Object(mybucket, mykey).put(ACL='public-read', Body=bytes(image))

我觉得这有点奇怪,因为buf.read()已经应该返回类型bytes的对象,但是我确实不知道,B/C现在可以工作。

最新更新