Boto3のPaginatorを利用したデータ取得方法

この記事では、AWS LambdaのPythonプログラムでBoto3のPaginatorを利用する方法について紹介します。

Paginatorとは

Paginatorとは、AWS Boto3ライブラリが提供する機能で、大量のデータを分割して取得する際に便利です。

これによりコードが簡潔になり、修正や機能追加、他の開発者がコードを読む際の負担を減らす事ができます。

なぜPaginatorを利用するのか

Boto3のAPIの中には、すべての結果を一度の実行で返すことができないものがあります。

特に、大量のデータを扱う場合、NextTokenといった戻り値を利用した複数回のAPI実行が必要となります。

Paginatorを利用することで、これらの処理を自動化し、簡潔なコードで実装することができます。

InspectorのAPIを使用した失敗例

エラーが発生するコード

ここでは、Amazon Inspectorを使用して検出結果一覧を取得する際の失敗例を紹介します。

※ Amazon Inspectorは、ソフトウェアやネットワークの状態をスキャンして、脆弱性を重大度別に管理するサービスです。

import boto3

def lambda_handler(event, context):
    inspector_client = boto3.client('inspector2')
    high_finding_list = []
    next_token = ""
    while(True):
        response = inspector_client.list_findings(
            filterCriteria={
                'severity': [
                    {
                        'comparison': 'EQUALS',
                        'value': 'HIGH'
                    }
                ]
            },
            maxResults=100,
            nextToken=next_token,
        )
        high_finding_list.extend(response['findings'])
        if 'nextToken' in response:
            next_token = response['nextToken']
        else:
            break

エラー内容

「list_findings」のような一部関数では、上記のコードのようにwhile文を使った処理を実行すると以下のようなエラーが発生します。

"errorMessage": "An error occurred (ValidationException) when calling the ListFindings operation:"

このエラーは、先ほどのコードのnext_tokenをNoneやnullに変更しても解決しません。

この処理では、while文の中で最初に実行される「list_findings」でnextTokenが存在することで失敗しています。

最初の一回をループ外で実行する方法や条件分岐による記述方法もありますが、Paginatorを利用することでより簡潔なコードにすることが可能です。

Paginatorの使い方

Paginatorを利用することでコードが簡潔になり、複雑なループ処理を避けることができます。

前提条件

  • 適切なタイムアウトの時間が設定されている
    • AWSのLambdaは1回の呼び出しに対して、処理時間が最長15分の制限がある
    • 大量のデータを処理するために実行時間の設定を変更する
  • 適切なメモリ容量が設定されている
    • 大量のデータを処理するために必要なメモリ容量を確保する
  • Lambdaのロールに適切な権限を持つポリシーが付与されている
    • API呼び出しを行うために、Lambda関数に必要なアクセス権限を設定する

処理が成功するコード

以下に、Paginatorを利用したInspectorの検出結果一覧を取得するコードを示します。

import boto3

def lambda_handler(event, context):
    inspector_client = boto3.client('inspector2')
    paginator = inspector_client.get_paginator('list_findings')

    high_finding_list = []
    response_iterator = paginator.paginate(
        filterCriteria={
            'severity': [
                {
                    'comparison': 'EQUALS',
                    'value': 'HIGH'
                }
            ]
        }
    )
    for response in response_iterator:
        high_finding_list.extend(response['findings'])

このコードでは、paginator = inspector_client.get_paginator('list_findings')のように、実行したいAPIに対してget_paginatorを使用することでPaginatorを利用しています。

また、list_findingsの引数であるfilterCriteriaのように、Paginatorでは通常のAPIと同じ引数を扱うことが可能です。

Paginatorが利用できるAPIは公式ドキュメントに記載がありますので、詳細な利用方法については、Boto3ドキュメントをご確認ください。

まとめ

以上がPaginatorを利用したデータ取得方法となります。

Paginatorを活用することで、AWSリソースからのデータ取得がより効率的に行えるようになります。

日常的にAWSを利用している方でも、特定のユースケースにおいてPaginatorの使い方を知っておくと、より効率的なシステム構築が可能です。

実際にPaginatorが必要になる場合は、Lambdaの実行時間やメモリ容量にもご注意ください。

執筆担当者プロフィール
山口 和真

山口 和真(日本ビジネスシステムズ株式会社)

2023年度新卒入社。プロフェッショナルサービス事業本部に所属。 システム基盤の設計や構築に興味があります。

担当記事一覧