将内存中的 HTML 保存到 S3 AWS Python Boto3

smg*_*ist 5 amazon-s3 amazon-web-services python-3.x boto3

import boto3
from io import StringIO
s3 = boto3.client('s3')

display = # Altair Charting

buff = StringIO(display.save(str_obj, 'html'))

s3.upload_fileobj(buff.read(), BUCKET, 'index.html')
Run Code Online (Sandbox Code Playgroud)

我认为完整的示例会使问题变得复杂,因此我将 Altair 图表注释掉了。

无论如何,我尝试实施大量将对象和文件保存到 AWS S3 存储桶的建议,但我不理解。

保存到磁盘非常简单:

display.save('index.html')
Run Code Online (Sandbox Code Playgroud)

比较起来,将其放到 S3 上似乎极其困难。我不确定我在这里缺少什么。也许这upload_fileobj不是正确的方法,但我一直在努力使这项工作可行。

该方法的具体错误是ValueError: Fileobj must implement read

更新:

buff = StringIO(display.save('str.html'))

s3.put_object(
   Bucket=BUCKET, 
   Key=f'{DASHBOARD}{mkt_type}/{symbol}/index.html',
   Body=buff.read()
   )
Run Code Online (Sandbox Code Playgroud)

index.html结果是我的存储桶上有 0 字节文件

更新2:

str_obj = StringIO()
display.save(str_obj, 'html')
buff = str_obj.read()

s3.put_object(
    Bucket=BUCKET, 
    Key=f'{DASHBOARD}{mkt_type}/{symbol}/index.html',
    Body=buff
    )
Run Code Online (Sandbox Code Playgroud)

这也是行不通的。我简直不敢相信将文件保存到 S3 会如此复杂。事后注意:我没有getvalue()所需的方法buff

解决方案:这不是我第一次遇到 S3 文件的困扰,因此我可能会将其留作将来参考。也就是说,我仍然不清楚为什么我无法以字符串形式保存“.html”文件。

import boto3
from io import StringIO
s3 = boto3.client('s3')

display = # Altair Charting

str_obj = StringIO() # instantiate in-memory string object
display.save(str_obj, 'html') # saving to memory string object
buf = str_obj.getvalue().encode() # convert in-memory string to bytes

# Upload as bytes
s3.put_object(
    Bucket=BUCKET, 
    Key=f'{DASHBOARD}{mkt_type}/{symbol}/index.html', 
    Body=buf
    )
Run Code Online (Sandbox Code Playgroud)

Sam*_*uel 3

来自 boto3 文档: put_object

Body=b'字节'|文件,

这意味着 Body 应该是文件句柄或字节字符串。所以有(至少)2种可能的上传方式:

通过将文件句柄传递给 Body:

with open('index.hml', 'rb') as f:
    s3.put_object(Bucket=BUCKET, Key=f'{DASHBOARD}{mkt_type}/{symbol}/index.html', Body=f)
Run Code Online (Sandbox Code Playgroud)

通过将字节字符串传递给 Body(假设 display.save() 返回字符串):

buf = display.save('str.html').encode() # converting str to bytes
s3.put_object(Bucket=BUCKET, Key=f'{DASHBOARD}{mkt_type}/{symbol}/index.html', Body=buf)
Run Code Online (Sandbox Code Playgroud)