Python Boto3:尝试从AWS S3下载文件时出错

13 浏览
0 Comments

Python Boto3:尝试从AWS S3下载文件时出错

你好,

我正在尝试从一个非常大的S3存储桶下载所有的文件。我是这样连接到S3的:

client = boto3.client('s3', 
aws_access_key_id=tempCredentials.credentials.access_key,
aws_secret_access_key = tempCredentials.credentials.secret_key,                                 
aws_session_token=tempCredentials.credentials.session_token)

然后我执行以下操作:

# 这将遍历并将字典填充为指定桶中的键
paginator = client.get_paginator("list_objects")
page_iterator = paginator.paginate(Bucket=bucket["Name"])
l = 0
# 我们将有一个列表来保存所有的键
key_list = []
for i in page_iterator:
    c = i["Contents"]
    for j in c:
          key_list.append(j["Key"])
    for j in key_list:
        download(bucket["Name"], j, "/Users/ahussain/Desktop/S3_Scrubber/" + file_name_helper(j), client)

其中,我的下载函数如下:

def download(bucket_name, key, path, client):
    key_name = key 
    print("正在下载 %s..." % str(key))
    client.download_file(bucket_name, key, path)
    print("下载 %s 完成!" % str(key))
    return key_name

发生的情况是,我成功遍历了存储桶并下载了相当一部分的键,但是过了一会儿,程序停止下载键并给出了以下错误:

botocore.exceptions.ClientError: An error occurred (400) when calling the HeadObject operation: Bad Request

我猜想是因为我的会话过期了,因为我使用的是MFA来访问这个S3,但我不确定。有人遇到过这个错误吗?

0
0 Comments

问题的原因是临时凭证的有效期只有一个小时。根据IAM文档,临时凭证的最小有效期是15分钟(900秒),最大有效期是1小时(3600秒)。如果希望临时凭证在1小时之前过期,需要传递这个值。

根据一个开放的bug(https://github.com/boto/boto3/issues/443),boto3库不支持长时间操作的临时凭证刷新。因此,如果在大约1小时后出现错误,很可能是这个原因。

解决方法是在代码中处理临时凭证的刷新。可以使用以下代码示例来刷新临时凭证:

import boto3
# 创建S3客户端
s3 = boto3.client('s3')
# 获取当前的临时凭证
session = boto3.Session()
credentials = session.get_credentials()
current_credentials = credentials.get_frozen_credentials()
# 刷新临时凭证
refreshed_credentials = current_credentials.refresh()
# 更新S3客户端的凭证
s3._request_signer._credentials = refreshed_credentials

这样,就可以在进行长时间操作时刷新临时凭证,避免出现错误。

0
0 Comments

在使用Python的Boto3库下载AWS S3中的文件时出现错误。据我了解,您可以增加凭证的有效期限,最长可达12小时,而不是1小时。您可以前往IAM > 角色 > 指定的角色 > 编辑会话持续时间来进行修改。

根据IAM文档的说明,最大会话持续时间由CLI/API会话持续时间的最大值确定,最长可达12小时。如果您的操作可能超过1小时但不超过12小时,那么修改会话持续时间可能会解决您的问题。

如果操作时间超过12小时,您可以考虑修改脚本以刷新凭证。不过,老实说,我不确定如何操作或者是否可行,但是这个SO回答和文档可能会对您有所帮助。

0