如何在Heroku上使用Boto3将文件上传到S3?

3

所有在线示例似乎都使用boto。我应该使用什么代码来使用boto3上传文件到S3?

我正在尝试使用官方文档中的代码,但是我遇到了版本4身份验证失败的错误。


请尝试在网络上搜索:https://boto3.readthedocs.io/en/latest/ - Shiv
为了后人,官方文档通常会遗漏非常关键的点。这就是本篇文章的目的所在。 - Jeremy T
哪个关键点?快速入门似乎正是您所寻找的。 - AChampion
1
region 可以在配置文件中设置(如快速入门中所述),而 region_namesessionresource 的文档中有清晰的解释。顺便提一下,您可能想要在 .aws/config 中探索配置文件,并使用 session 对象。 - AChampion
在我的情况下它无法实现。我更新了问题,指出了我的具体情况以及为什么需要将其包含在资源调用中。 - Jeremy T
显示剩余2条评论
4个回答

7

按照快速入门指南将您的密钥放入密钥文件,然后使用以下代码:

       import boto3
       s3 = boto3.resource(service_name='s3', region_name='REGION_NAME')
       data = open('PATH_TO_FILE_ON_DISK', 'rb')
       s3.Bucket('BUCKET_NAME').put_object(Key='FILENAME_ON_S3', Body=data)

官方文档没有明确说明区域名称是必需的,否则可能会出现错误,并且无法在Heroku上存储区域的配置文件。它必须包含在资源调用中。

这并没有回答问题“新语法是什么?” - Shiv
它哪里不行了呢?如果你复制粘贴这段代码,它能完美运行。无论如何,没有关系。我只是需要填充一些空白,因为我已经搜寻了将近四天这段代码片段。文档不够清晰。 - Jeremy T
好的,我不想在这个问题上争论了,我会撤回我的反对票。 - Shiv
我的投票已经锁定,无法取消,所以请您对您的回答进行一些编辑。 - Shiv
@AChampion,恐怕你是错的。我直接从我的正在生产中工作的项目中复制了代码。PATH_TO_FILE_ON_DISK确实就像我描述的那样。我的回答可能不完整,如果是这样,我很乐意接受编辑,但它并不是错误的。 - Jeremy T
显示剩余6条评论

1
由于Heroku无法访问您的 AWS配置文件,因此您需要使用环境变量。然后,您可以使用各种s3文件上传方法之一。
from os import getenv

import boto3

boto_kwargs = {
    "aws_access_key_id": getenv("AWS_ACCESS_KEY_ID"),
    "aws_secret_access_key": getenv("AWS_SECRET_ACCESS_KEY"),
    "region_name": getenv("AWS_REGION"),
}

s3_client = boto3.Session(**boto_kwargs).client("s3")

s3_client.upload_fileobj(<f>, <bucket_name>, <object_name>)

0

最近,Heroku发布了一篇有关在Heroku中将文件上传到S3的好文章。使用Python直接上传到S3

根据说明,您需要在Heroku应用程序配置变量中指定AWS凭据和存储桶名称。

为了使您的应用程序能够访问AWS凭据以签署上传请求,它们需要添加为Heroku中的配置变量:

$ heroku config:set AWS_ACCESS_KEY_ID =xxx AWS_SECRET_ACCESS_KEY =yyy
Adding config vars and restarting app... done, v21
AWS_ACCESS_KEY_ID     => xxx
AWS_SECRET_ACCESS_KEY => yyy

除了AWS访问凭证之外,还需设置您的目标S3存储桶名称:
heroku config:set S3_BUCKET = zzz
Adding config vars and restarting app... done, v21
S3_BUCKET     => zzz

注意:如果您在部署之前进行本地测试,请记得将凭据添加到本地计算机的环境中。如何通过配置文件实现已经在上面进行了说明。


0

仅供参考,以下是您可以解决所有新地区使用v4身份验证问题的方法-在配置文件中设置signature_version

--- .aws/config ---
[default]
output = json

[profile myprofile]
region = REGION_NAME
s3=
  signature_version = s3
#  addressing_style = path

--- .aws/credentials ---
[myprofile]
aws_access_key_id = <access-key>
aws_secret_access_key = <secret-key>

--- python ---
import boto3

session = boto3.Session(profile_name='myprofile')
s3 = session.resource('s3')
with open('PATH_TO_FILE_ON_DISK', 'rb') as data:
    s3.Object('BUCKET_NAME', 'FILENAME_ON_S3').put(Body=data)

或者:

s3.Object('BUCKET_NAME', 'FILENAME_ON_S3').upload_file('PATH_TO_FILE_ON_DISK')

4
除非您知道某个隐藏功能,否则在Heroku上配置文件将不起作用。 - Jeremy T

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