使用 s3.get_paginator('list_objects_v2') 时 AWS 错误"Calling the invoke API action failed with this mes



一些第三方应用程序一天内将大约10000个对象上传到我的bucket+前缀中。我的要求是获取在过去24小时内上传到我的bucket+前缀的所有对象。

我的bucket+前缀中有这么多文件。

所以我认为当我打电话给时

response = s3_paginator.paginate(Bucket=bucket,Prefix='inside-bucket-level-1/', PaginationConfig={"PageSize": 1000})

那么它可能会多次调用S3 API,这可能就是它显示超过速率错误的原因。

下面是我的Python Lambda函数。

import json
import boto3
import time
from datetime import datetime, timedelta

def lambda_handler(event, context):
s3 = boto3.client("s3")
from_date = datetime.today() - timedelta(days=1)
string_from_date = from_date.strftime("%Y-%m-%d, %H:%M:%S")
print("Date :", string_from_date)
s3_paginator = s3.get_paginator('list_objects_v2')
list_of_buckets = ['kush-dragon-data']
bucket_wise_list = {}
for bucket in list_of_buckets:
response = s3_paginator.paginate(Bucket=bucket,Prefix='inside-bucket-level-1/', PaginationConfig={"PageSize": 1000})
filtered_iterator = response.search(
"Contents[?to_string(LastModified)>='"" + string_from_date + ""'].Key")
keylist = []
for key_data in filtered_iterator:
if "/" in key_data:
splitted_array = key_data.split("/")
if len(splitted_array) > 1:
if splitted_array[-1]:
keylist.append(splitted_array[-1])
else:
keylist.append(key_data)
bucket_wise_list.update({bucket: keylist})
print("Total Number Of Object = ", bucket_wise_list)
# TODO implement
return {
'statusCode': 200,
'body': json.dumps(bucket_wise_list)
}

所以当我们执行上面的Lambda函数时,它会显示下面的错误。

";调用调用API操作失败,返回以下消息:超过速率">

有人能帮助解决这个错误并达到我的要求吗?

这可能是由于您的帐户限制,您应该在重试间隔几秒的情况下添加重试或增加页面大小

这很可能是由于您达到了AWS S3 API调用的配额限制。";更大的锤子";解决方案是请求增加配额,但若您不想这样做,还有另一种方法可以使用内置的botocore.Config重试,例如:

import json
import time
from datetime import datetime, timedelta
from boto3 import client
from botocore.config import Config
config = Config(
retries = {
'max_attempts': 10,
'mode': 'standard'
}
)
def lambda_handler(event, context):
s3 = client('s3', config=config)
###ALL OF YOUR CURRENT PYTHON CODE EXACTLY THE WAY IT IS###

此配置将使用指数递增的睡眠计时器以达到最大重试次数。来自文档:

  • 任何重试尝试都将包括一个基数因子为2的指数退避,最大退避时间为20秒

还有一种adaptive模式,它仍然是实验性的。有关更多信息,请参阅有关botocore.Config重试的文档

另一个(不太强大的IMO)选项是编写自己的分页器,并编程睡眠,尽管你可能只想在99.99%的情况下使用内置回退(即使你必须编写自己的寻呼器)。(此代码未经测试,甚至不是异步的,因此睡眠时间将是页面响应等待时间之外的时间。要使"睡眠时间"精确为sleep_secs,您需要使用concurrent.futuresasyncio(AWS内置的分页器大多使用concurrent.futures)):

from boto3 import client
from typing import Generator
from time import sleep
def get_pages(bucket:str,prefix:str,page_size:int,sleep_secs:float) -> Generator:
s3 = client('s3')
page:dict = client.list_objects_v2(
Bucket=bucket,
MaxKeys=page_size,
Prefix=prefix
)
next_token:str = page.get('NextContinuationToken')
yield page
while(next_token):
sleep(sleep_secs)
page = client.list_objects_v2(
Bucket=bucket,
MaxKeys=page_size,
Prefix=prefix,
ContinuationToken=next_token
)
next_token = page.get('NextContinuationToken')
yield page

相关内容

最新更新