python-3.x 如何使用Boto3分页

hkmswyz6  于 2023-05-08  发布在  Python
关注(0)|答案(5)|浏览(197)

背景:
默认情况下,列出IAM用户的AWS操作返回的最大值为50。
阅读下面的文档(链接),我运行以下代码,并通过将“MaxItems”设置为1000返回一组完整的数据。

paginator = client.get_paginator('list_users')
response_iterator = paginator.paginate(
 PaginationConfig={
     'MaxItems': 1000,
     'PageSize': 123})
for page in response_iterator:
    u = page['Users']
    for user in u:
        print(user['UserName'])

https://boto3.readthedocs.io/en/latest/reference/services/iam.html#IAM.Paginator.ListUsers
问题:
例如,如果“MaxItems”设置为10,那么循环遍历结果的最佳方法是什么?
我用下面的代码进行了测试,但它只在'IsTruncated' == False之前循环了2次迭代,并导致“KeyError:“标记”。不知道为什么会发生这种情况,因为我知道有超过200个结果。

marker = None

while True:
    paginator = client.get_paginator('list_users')
    response_iterator = paginator.paginate( 
        PaginationConfig={
            'MaxItems': 10,
            'StartingToken': marker})
    #print(response_iterator)
    for page in response_iterator:
        u = page['Users']
        for user in u:
            print(user['UserName'])
            print(page['IsTruncated'])
            marker = page['Marker']
            print(marker)
        else:
            break
t98cgbkg

t98cgbkg1#

(答案重写)注意,分页器包含一个与文档不一致的错误(反之亦然)。MaxItems在总项目数超过MaxItems数时不返回Marker或NextToken。实际上,PageSize是控制Marker/NextToken指示符返回的那个。

import sys
import boto3
iam = boto3.client("iam")
marker = None
while True:
    paginator = iam.get_paginator('list_users')
    response_iterator = paginator.paginate( 
        PaginationConfig={
            'PageSize': 10,
            'StartingToken': marker})
    for page in response_iterator:
        print("Next Page : {} ".format(page['IsTruncated']))
        u = page['Users']
        for user in u:
            print(user['UserName'])
    try:
        marker = response_iterator['Marker']
        print(marker)
    except KeyError:
        sys.exit()

你的代码不起作用不是你的错。分页器中的MaxItems似乎成为了一个“阈值”指标。具有讽刺意味的是,原始boto3.iam.list_users中的MaxItems仍然可以像上面提到的那样工作。
如果选中boto3.iam.list_users,您会注意到您忽略了Marker,否则必须输入一个值。显然,*paginator不是所有boto 3类list_ 方法的 Package 器。

import sys
import boto3
iam = boto3.client("iam")
marker = None
while True:
    if marker:
        response_iterator = iam.list_users(
            MaxItems=10,
            Marker=marker
        )
    else:
        response_iterator = iam.list_users(
            MaxItems=10
        )
    print("Next Page : {} ".format(response_iterator['IsTruncated']))
    for user in response_iterator['Users']:
        print(user['UserName'])

    try:
        marker = response_iterator['Marker']
        print(marker)
    except KeyError:
        sys.exit()

你可以继续关注我在boto 3 github上提交的问题。根据成员,您可以在paginate()之后调用build_full_result,这将显示期望的行为。

q43xntqr

q43xntqr2#

这个密码对我没用。它总是在最后一页上删除剩余的项目,并且不将它们包含在结果中。当我知道我有68个账户时,给了我60个账户的结果。最后一个结果页面不会附加到我的帐户用户名列表中。我担心上面的这些例子都在做同样的事情,而人们在结果中没有注意到这一点。
这似乎过于复杂,通过分页与任意大小的目的是什么?
这应该是简单的,并给你一个完整的清单。

import boto3
iam = boto3.client("iam")
paginator = iam.get_paginator('list_users')
response_iterator = paginator.paginate()
accounts=[]
for page in response_iterator:
    for user in page['Users']:
        accounts.append(user['UserName'])
len(accounts)
68
ldfqzlk8

ldfqzlk83#

这篇文章已经很老了,但是由于缺乏简洁的文档,我想把我的代码分享给所有正在为此而奋斗的人
这里有两个简单的例子,我如何解决它使用Boto 3的分页希望这有助于您了解它是如何工作的
Boto 3官方分页文档:https://boto3.amazonaws.com/v1/documentation/api/latest/guide/paginators.html
AWS API指定第一个令牌应为$null(Python中为None):https://docs.aws.amazon.com/powershell/latest/reference/items/Get-SSMParametersByPath.html
示例:
第一个例子对于像我这样努力理解它是如何工作的人来说并不复杂:

def read_ssm_parameters():
    page_iterator = paginator.paginate(
        Path='path_to_the_parameters',
        Recursive=True,
        PaginationConfig={
        'MaxItems': 10,
        'PageSize': 10,
        }
    )

    while myNextToken:
        for page in page_iterator:
             print('# This is new page')
             print(page['Parameters'])
             if 'NextToken' in page.keys():
                 print(page['NextToken'])
                 myNextToken=page['NextToken']
             else:
                 myNextToken=False

    page_iterator = paginator.paginate(
        Path=baseSSMPath,
        Recursive=True,
        PaginationConfig={
            'MaxItems': 10,
            'PageSize': 10,
            'StartingToken': myNextToken
        }
    )

第二个例子,代码减少,但没有使用递归的复杂性

def read_ssm_parameters(myNextToken='None'):
    while myNextToken:
        page_iterator = paginator.paginate(
            Path='path_to_the_parameters',
            Recursive=True,
            PaginationConfig={
                'MaxItems': 10,
                'PageSize': 10,
                'StartingToken': myNextToken
            }
        )

        for page in page_iterator:
            if 'NextToken' in page.keys():
                print('# This is a new page')
                myNextToken=page['NextToken']
                print(page['Parameters'])
            else:
                # Exit if there are no more pages to read
                myNextToken=False

希望这有帮助!

sycxhyv7

sycxhyv74#

正确答案在上面的一条评论中。我以前也遇到过这个问题。我管理着56个aws账户,在遍历所有这些账户时,我注意到'list_users'只返回100个用户。在深入研究这个问题后,我发现了这个线程和与这个问题相关的boto3 github问题。调用build_full_result()将返回完整的用户列表。

paginator = client.get_paginator('list_users') 
users = paginator.paginate().build_full_result()
u1ehiz5o

u1ehiz5o5#

我将在这里发布我的解决方案,希望能帮助其他人更快地完成他们的工作,而不是摆弄写得令人惊讶的API调用。
我的用例是使用SecurityHub.Client.describe_standards_controls函数列出所有SecurityHubControlId。

controlsResponse = sh_client.describe_standards_controls(
StandardsSubscriptionArn = enabledStandardSubscriptionArn)

controls = controlsResponse.get('Controls')

# This is the token for the 101st item in the list.
nextToken = controlsResponse.get('NextToken') 

# Call describe_standards_controls with the token set at item 101 to get the next 100 results 
controlsResponse1 = sh_client.describe_standards_controls(
StandardsSubscriptionArn = enabledStandardSubscriptionArn, NextToken=nextToken)

controls1 = controlsResponse1.get('Controls')

# And make the two lists into one
controls.extend(controls1)

否,您有指定订阅标准(例如AWS基础标准)的所有SH标准控件的列表
例如,如果我想得到所有的ControlId,我可以迭代'controls'列表并执行
controlId= control.get(“ControlId”)
响应中的其他字段也是如此

相关问题