Python Boto3:尝试从AWS S3下载文件时出错
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,但我不确定。有人遇到过这个错误吗?
问题的原因是临时凭证的有效期只有一个小时。根据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
这样,就可以在进行长时间操作时刷新临时凭证,避免出现错误。