📖

boto3で出力結果が途中で途切れてしまう時にNextTokenやpaginetorを使って続きを見る

2021/10/02に公開

boto3で何かしらの出力をしたときに、全ての結果が1回で出力されないことがある。
以下はクォータのあるAWSサービスのサービスコードというものをboto3で取得、出力しているが、出力結果がAmazon EC2 Auto Scaling で途切れてしまっている。AWSのサービスは多岐にわたるので、A~ZのAで終わることはもちろんあり得ない。

>>> import boto3
>>> import pprint
>>> client = boto3.client('service-quotas')
>>> pprint.pprint(response)
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1986',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:13:34 GMT',
                                      'x-amzn-requestid': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'AWSCloudMap', 'ServiceName': 'AWS Cloud Map'},
              {'ServiceCode': 'a4b', 'ServiceName': 'Alexa for Business'},
              {'ServiceCode': 'access-analyzer',
               'ServiceName': 'Access Analyzer'},
              {'ServiceCode': 'acm',
               'ServiceName': 'AWS Certificate Manager (ACM)'},
              {'ServiceCode': 'acm-pca',
               'ServiceName': 'AWS Certificate Manager Private Certificate '
                              'Authority (ACM PCA)'},
              {'ServiceCode': 'airflow',
               'ServiceName': 'Amazon Managed Workflows for Apac内容 Airflow'},
              {'ServiceCode': 'amplify', 'ServiceName': 'AWS Amplify'},
              {'ServiceCode': 'apigateway',
               'ServiceName': 'Amazon API Gateway'},
              {'ServiceCode': 'appconfig', 'ServiceName': 'AWS AppConfig'},
              {'ServiceCode': 'appflow', 'ServiceName': 'Amazon AppFlow'},
              {'ServiceCode': 'application-autoscaling',
               'ServiceName': 'Application Auto Scaling'},
              {'ServiceCode': 'application-cost-profiler',
               'ServiceName': 'AWS Application Cost Profiler'},
              {'ServiceCode': 'appmesh', 'ServiceName': 'AWS App Mesh'},
              {'ServiceCode': 'apprunner', 'ServiceName': 'AWS App Runner'},
              {'ServiceCode': 'appstream2',
               'ServiceName': 'Amazon AppStream 2.0'},
              {'ServiceCode': 'appsync', 'ServiceName': 'AWS AppSync'},
              {'ServiceCode': 'aps',
               'ServiceName': 'Amazon Managed Prometheus'},
              {'ServiceCode': 'athena', 'ServiceName': 'Amazon Athena'},
              {'ServiceCode': 'auditmanager',
               'ServiceName': 'AWS Audit Manager'},
              {'ServiceCode': 'autoscaling',
               'ServiceName': 'Amazon EC2 Auto Scaling'}]}
>>> 
>>> 

この中途半端な出力結果にはNextTokenというものがくっついてくるので、それを使うと続きの結果を見ることが出来る。

これのこと。

{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',

boto3 のservicequotasのlist_servicesのRequest Syntax(処理に必要な記述内容)は以下のようになっている。

response = client.list_services(
    NextToken='string',
    MaxResults=123
)

このNextToken=の部分に、先ほどの、

{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',

これを渡してあげれば、後続の結果を得ることが出来る。
そのまま文字列で渡すのは現実的ではない。
client.list_servicesの出力結果は辞書型なので、変数responseに格納されている辞書のキー'NextToken'を指定しその値を取得し、NextToken=の引数として使用する。

>>> response = client.list_services(NextToken=response['NextToken'])
>>> pprint.pprint(response)
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1847',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:25:20 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'autoscaling-plans',
               'ServiceName': 'AWS Auto Scaling Plans'},
              {'ServiceCode': 'backup', 'ServiceName': 'AWS Backup'},
              {'ServiceCode': 'batch', 'ServiceName': 'AWS Batch'},
              {'ServiceCode': 'braket', 'ServiceName': 'Amazon Braket'},
              {'ServiceCode': 'bugbust', 'ServiceName': 'AWS Bugbust'},
              {'ServiceCode': 'cassandra',
               'ServiceName': 'Amazon Keyspaces (for Apache Cassandra)'},
              {'ServiceCode': 'ce', 'ServiceName': 'AWS Cost Explorer'},
              {'ServiceCode': 'chatbot', 'ServiceName': 'AWS Chatbot'},
              {'ServiceCode': 'chime', 'ServiceName': 'Amazon Chime'},
              {'ServiceCode': 'cloud9', 'ServiceName': 'AWS Cloud9'},
              {'ServiceCode': 'cloudformation',
               'ServiceName': 'AWS CloudFormation'},
              {'ServiceCode': 'cloudfront', 'ServiceName': 'Amazon CloudFront'},
              {'ServiceCode': 'cloudhsm', 'ServiceName': 'AWS CloudHSM'},
              {'ServiceCode': 'cloudsearch',
               'ServiceName': 'Amazon CloudSearch'},
              {'ServiceCode': 'cloudshell', 'ServiceName': 'AWS CloudShell'},
              {'ServiceCode': 'cloudtrail', 'ServiceName': 'AWS CloudTrail'},
              {'ServiceCode': 'codeartifact',
               'ServiceName': 'AWS CodeArtifact'},
              {'ServiceCode': 'codebuild', 'ServiceName': 'AWS CodeBuild'},
              {'ServiceCode': 'codecommit', 'ServiceName': 'AWS CodeCommit'},
              {'ServiceCode': 'codedeploy', 'ServiceName': 'AWS CodeDeploy'}]}

そうすると、AWS Auto Scaling Plansから始まる続きの結果が出力できた。
ただこれでもまだ全結果を出力できていない。
しかし1回1回同じことを繰り返すのは辛いので、Paginetorというものを使う。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/service-quotas.html#ServiceQuotas.Paginator.ListServices

Paginatorを生成して、

paginator = client.get_paginator('list_services')

Request Syntaxはこんな感じ。

response_iterator = paginator.paginate(
    PaginationConfig={
        'MaxItems': 123,
        'PageSize': 123,
        'StartingToken': 'string'
    }
)

実際にやってみる。paginatorを作成して、for文でループさせる形にする。
PaginationConfigにrequired(必須)なものは無いので無くてもかまわない。
※他のサービス(例えばS3とか)のpaginatorによってはrequiredなパラメータも出てくる。

>>> paginator = client.get_paginator('list_services')
>>> for result in paginator.paginate():
...     pprint.pprint(result)
... 
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEI長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1986',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:24 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'AWSCloudMap', 'ServiceName': 'AWS Cloud Map'},
              {'ServiceCode': 'a4b', 'ServiceName': 'Alexa for Business'},
              {'ServiceCode': 'access-analyzer',
               'ServiceName': 'Access Analyzer'},
              {'ServiceCode': 'acm',
               'ServiceName': 'AWS Certificate Manager (ACM)'},
              {'ServiceCode': 'acm-pca',
               'ServiceName': 'AWS Certificate Manager Private Certificate '
                              'Authority (ACM PCA)'},
              {'ServiceCode': 'airflow',
               'ServiceName': 'Amazon Managed Workflows for Apache Airflow'},
              {'ServiceCode': 'amplify', 'ServiceName': 'AWS Amplify'},
              {'ServiceCode': 'apigateway',
               'ServiceName': 'Amazon API Gateway'},
              {'ServiceCode': 'appconfig', 'ServiceName': 'AWS AppConfig'},
              {'ServiceCode': 'appflow', 'ServiceName': 'Amazon AppFlow'},
              {'ServiceCode': 'application-autoscaling',
               'ServiceName': 'Application Auto Scaling'},
              {'ServiceCode': 'application-cost-profiler',
               'ServiceName': 'AWS Application Cost Profiler'},
              {'ServiceCode': 'appmesh', 'ServiceName': 'AWS App Mesh'},
              {'ServiceCode': 'apprunner', 'ServiceName': 'AWS App Runner'},
              {'ServiceCode': 'appstream2',
               'ServiceName': 'Amazon AppStream 2.0'},
              {'ServiceCode': 'appsync', 'ServiceName': 'AWS AppSync'},
              {'ServiceCode': 'aps',
               'ServiceName': 'Amazon Managed Prometheus'},
              {'ServiceCode': 'athena', 'ServiceName': 'Amazon Athena'},
              {'ServiceCode': 'auditmanager',
               'ServiceName': 'AWS Audit Manager'},
              {'ServiceCode': 'autoscaling',
               'ServiceName': 'Amazon EC2 Auto Scaling'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1847',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:24 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'autoscaling-plans',
               'ServiceName': 'AWS Auto Scaling Plans'},
              {'ServiceCode': 'backup', 'ServiceName': 'AWS Backup'},
              {'ServiceCode': 'batch', 'ServiceName': 'AWS Batch'},
              {'ServiceCode': 'braket', 'ServiceName': 'Amazon Braket'},
              {'ServiceCode': 'bugbust', 'ServiceName': 'AWS Bugbust'},
              {'ServiceCode': 'cassandra',
               'ServiceName': 'Amazon Keyspaces (for Apache Cassandra)'},
              {'ServiceCode': 'ce', 'ServiceName': 'AWS Cost Explorer'},
              {'ServiceCode': 'chatbot', 'ServiceName': 'AWS Chatbot'},
              {'ServiceCode': 'chime', 'ServiceName': 'Amazon Chime'},
              {'ServiceCode': 'cloud9', 'ServiceName': 'AWS Cloud9'},
              {'ServiceCode': 'cloudformation',
               'ServiceName': 'AWS CloudFormation'},
              {'ServiceCode': 'cloudfront', 'ServiceName': 'Amazon CloudFront'},
              {'ServiceCode': 'cloudhsm', 'ServiceName': 'AWS CloudHSM'},
              {'ServiceCode': 'cloudsearch',
               'ServiceName': 'Amazon CloudSearch'},
              {'ServiceCode': 'cloudshell', 'ServiceName': 'AWS CloudShell'},
              {'ServiceCode': 'cloudtrail', 'ServiceName': 'AWS CloudTrail'},
              {'ServiceCode': 'codeartifact',
               'ServiceName': 'AWS CodeArtifact'},
              {'ServiceCode': 'codebuild', 'ServiceName': 'AWS CodeBuild'},
              {'ServiceCode': 'codecommit', 'ServiceName': 'AWS CodeCommit'},
              {'ServiceCode': 'codedeploy', 'ServiceName': 'AWS CodeDeploy'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '2022',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:24 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'codeguru-profiler',
               'ServiceName': 'Amazon CodeGuru Profiler'},
              {'ServiceCode': 'codeguru-reviewer',
               'ServiceName': 'Amazon CodeGuru Reviewer'},
              {'ServiceCode': 'codepipeline',
               'ServiceName': 'AWS CodePipeline'},
              {'ServiceCode': 'cognito-identity',
               'ServiceName': 'Amazon Cognito Federated Identities'},
              {'ServiceCode': 'cognito-idp',
               'ServiceName': 'Amazon Cognito User Pools'},
              {'ServiceCode': 'cognito-sync',
               'ServiceName': 'Amazon Cognito Sync'},
              {'ServiceCode': 'comprehend', 'ServiceName': 'Amazon Comprehend'},
              {'ServiceCode': 'comprehendmedical',
               'ServiceName': 'Amazon Comprehend Medical'},
              {'ServiceCode': 'compute-optimizer',
               'ServiceName': 'AWS Compute Optimizer'},
              {'ServiceCode': 'connect', 'ServiceName': 'Amazon Connect'},
              {'ServiceCode': 'crowdscale-usagelimitservice',
               'ServiceName': 'Mechanical Turk'},
              {'ServiceCode': 'databrew', 'ServiceName': 'AWS Glue DataBrew'},
              {'ServiceCode': 'dataexchange',
               'ServiceName': 'AWS Data Exchange'},
              {'ServiceCode': 'datapipeline',
               'ServiceName': 'AWS Data Pipeline'},
              {'ServiceCode': 'datasync', 'ServiceName': 'AWS DataSync'},
              {'ServiceCode': 'dax',
               'ServiceName': 'Amazon DynamoDB Accelerator (DAX)'},
              {'ServiceCode': 'deeplens', 'ServiceName': 'AWS DeepLens'},
              {'ServiceCode': 'deepracer', 'ServiceName': 'AWS DeepRacer'},
              {'ServiceCode': 'directconnect',
               'ServiceName': 'AWS Direct Connect'},
              {'ServiceCode': 'discovery',
               'ServiceName': 'AWS Application Discovery Service'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEI長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '2170',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:24 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'dlm',
               'ServiceName': 'Amazon Data Lifecycle Manager'},
              {'ServiceCode': 'dms',
               'ServiceName': 'AWS Database Migration Service (AWS DMS)'},
              {'ServiceCode': 'docdb',
               'ServiceName': 'Amazon DocumentDB (with MongoDB compatibility)'},
              {'ServiceCode': 'ds', 'ServiceName': 'AWS Directory Service'},
              {'ServiceCode': 'dynamodb', 'ServiceName': 'Amazon DynamoDB'},
              {'ServiceCode': 'ebs',
               'ServiceName': 'Amazon Elastic Block Store (Amazon EBS)'},
              {'ServiceCode': 'ec2',
               'ServiceName': 'Amazon Elastic Compute Cloud (Amazon EC2)'},
              {'ServiceCode': 'ecr',
               'ServiceName': 'Amazon Elastic Container Registry (Amazon ECR)'},
              {'ServiceCode': 'ecs',
               'ServiceName': 'Amazon Elastic Container Service (Amazon ECS)'},
              {'ServiceCode': 'eks',
               'ServiceName': 'Amazon Elastic Kubernetes Service (Amazon EKS)'},
              {'ServiceCode': 'elastic-inference',
               'ServiceName': 'Amazon Elastic Inference'},
              {'ServiceCode': 'elasticache',
               'ServiceName': 'Amazon ElastiCache'},
              {'ServiceCode': 'elasticbeanstalk',
               'ServiceName': 'AWS Elastic Beanstalk'},
              {'ServiceCode': 'elasticfilesystem',
               'ServiceName': 'Amazon Elastic File System (EFS)'},
              {'ServiceCode': 'elasticloadbalancing',
               'ServiceName': 'Elastic Load Balancing (ELB)'},
              {'ServiceCode': 'elasticmapreduce', 'ServiceName': 'Amazon EMR'},
              {'ServiceCode': 'elastictranscoder',
               'ServiceName': 'Amazon Elastic Transcoder'},
              {'ServiceCode': 'es',
               'ServiceName': 'Amazon OpenSearch Service (successor to Amazon '
                              'Elasticsearch Service)'},
              {'ServiceCode': 'events',
               'ServiceName': 'Amazon EventBridge (CloudWatch Events)'},
              {'ServiceCode': 'fargate', 'ServiceName': 'AWS Fargate'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1897',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:25 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'finspace', 'ServiceName': 'Amazon FinSpace'},
              {'ServiceCode': 'firehose',
               'ServiceName': 'Amazon Kinesis Data Firehose'},
              {'ServiceCode': 'fis',
               'ServiceName': 'AWS Fault Injection Simulator'},
              {'ServiceCode': 'fms', 'ServiceName': 'AWS Firewall Manager'},
              {'ServiceCode': 'forecast', 'ServiceName': 'Amazon Forecast'},
              {'ServiceCode': 'frauddetector',
               'ServiceName': 'Amazon Fraud Detector'},
              {'ServiceCode': 'fsx', 'ServiceName': 'Amazon FSx'},
              {'ServiceCode': 'gamelift', 'ServiceName': 'Amazon GameLift'},
              {'ServiceCode': 'geo',
               'ServiceName': 'Amazon Location Service (Amazon Location)'},
              {'ServiceCode': 'glacier', 'ServiceName': 'Amazon Glacier'},
              {'ServiceCode': 'globalaccelerator',
               'ServiceName': 'AWS Global Accelerator'},
              {'ServiceCode': 'glue', 'ServiceName': 'AWS Glue'},
              {'ServiceCode': 'grafana',
               'ServiceName': 'Amazon Managed Grafana'},
              {'ServiceCode': 'greengrass',
               'ServiceName': 'AWS IoT Greengrass'},
              {'ServiceCode': 'guardduty', 'ServiceName': 'Amazon GuardDuty'},
              {'ServiceCode': 'iam',
               'ServiceName': 'AWS Identity and Access Management (IAM)'},
              {'ServiceCode': 'imagebuilder',
               'ServiceName': 'EC2 Image Builder'},
              {'ServiceCode': 'inspector', 'ServiceName': 'Amazon Inspector'},
              {'ServiceCode': 'iot', 'ServiceName': 'AWS IoT'},
              {'ServiceCode': 'iot1click', 'ServiceName': 'AWS IoT 1-Click'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1998',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:25 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'iotanalytics',
               'ServiceName': 'AWS IoT Analytics'},
              {'ServiceCode': 'iotcore', 'ServiceName': 'AWS IoT Core'},
              {'ServiceCode': 'iotdeviceadvisor',
               'ServiceName': 'AWS IoT Core Device Advisor'},
              {'ServiceCode': 'iotevents', 'ServiceName': 'AWS IoT Events'},
              {'ServiceCode': 'iotfleethub',
               'ServiceName': 'AWS IoT Fleet Hub'},
              {'ServiceCode': 'iotsitewise', 'ServiceName': 'AWS IoT SiteWise'},
              {'ServiceCode': 'iotthingsgraph',
               'ServiceName': 'AWS IoT Things Graph'},
              {'ServiceCode': 'iotwireless', 'ServiceName': 'AWS IoT Wireless'},
              {'ServiceCode': 'ivs',
               'ServiceName': 'Amazon Interactive Video Service'},
              {'ServiceCode': 'kafka',
               'ServiceName': 'Amazon Managed Streaming for Kafka (MSK)'},
              {'ServiceCode': 'kendra', 'ServiceName': 'Amazon Kendra'},
              {'ServiceCode': 'kinesis',
               'ServiceName': 'Amazon Kinesis Data Streams'},
              {'ServiceCode': 'kinesisanalytics',
               'ServiceName': 'Amazon Kinesis Data Analytics'},
              {'ServiceCode': 'kinesisvideo',
               'ServiceName': 'Amazon Kinesis Video Streams'},
              {'ServiceCode': 'kms',
               'ServiceName': 'AWS Key Management Service (AWS KMS)'},
              {'ServiceCode': 'lakeformation',
               'ServiceName': 'AWS Lake Formation'},
              {'ServiceCode': 'lambda', 'ServiceName': 'AWS Lambda'},
              {'ServiceCode': 'launchwizard',
               'ServiceName': 'AWS Launch Wizard For SQL Server'},
              {'ServiceCode': 'lex', 'ServiceName': 'Amazon Lex'},
              {'ServiceCode': 'license-manager',
               'ServiceName': 'AWS License Manager'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1979',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:25 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'lightsail', 'ServiceName': 'Amazon Lightsail'},
              {'ServiceCode': 'logs', 'ServiceName': 'Amazon CloudWatch Logs'},
              {'ServiceCode': 'lookoutequipment',
               'ServiceName': 'Amazon Lookout for Equipment'},
              {'ServiceCode': 'lookoutmetrics',
               'ServiceName': 'Amazon Lookout for Metrics'},
              {'ServiceCode': 'lookoutvision',
               'ServiceName': 'Amazon Lookout for vision'},
              {'ServiceCode': 'machinelearning',
               'ServiceName': 'Amazon Machine Learning'},
              {'ServiceCode': 'macie', 'ServiceName': 'Amazon Macie Classic'},
              {'ServiceCode': 'macie2', 'ServiceName': 'Amazon Macie'},
              {'ServiceCode': 'managedblockchain',
               'ServiceName': 'Amazon Managed Blockchain'},
              {'ServiceCode': 'mediaconnect',
               'ServiceName': 'AWS Elemental MediaConnect'},
              {'ServiceCode': 'mediaconvert',
               'ServiceName': 'AWS Elemental MediaConvert'},
              {'ServiceCode': 'medialive',
               'ServiceName': 'AWS Elemental MediaLive'},
              {'ServiceCode': 'mediapackage',
               'ServiceName': 'AWS Elemental MediaPackage'},
              {'ServiceCode': 'mediastore',
               'ServiceName': 'AWS Elemental MediaStore'},
              {'ServiceCode': 'mediatailor',
               'ServiceName': 'AWS Elemental MediaTailor'},
              {'ServiceCode': 'mgn', 'ServiceName': 'Application Migration'},
              {'ServiceCode': 'monitoring', 'ServiceName': 'Amazon CloudWatch'},
              {'ServiceCode': 'monitron', 'ServiceName': 'Amazon Monitron'},
              {'ServiceCode': 'mq', 'ServiceName': 'Amazon MQ'},
              {'ServiceCode': 'neptune', 'ServiceName': 'Amazon Neptune'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEI長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1995',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:25 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'network-firewall',
               'ServiceName': 'AWS Network Firewall'},
              {'ServiceCode': 'networkinsights',
               'ServiceName': 'VPC Reachability Analyzer'},
              {'ServiceCode': 'networkmanager',
               'ServiceName': 'AWS Network Manager'},
              {'ServiceCode': 'nimble', 'ServiceName': 'Amazon Nimble Studio'},
              {'ServiceCode': 'opsworks', 'ServiceName': 'AWS OpsWorks Stacks'},
              {'ServiceCode': 'opsworks-cm',
               'ServiceName': 'AWS OpsWorks for Chef Automate and AWS OpsWorks '
                              'for Puppet Enterprise'},
              {'ServiceCode': 'organizations',
               'ServiceName': 'AWS Organizations'},
              {'ServiceCode': 'personalize',
               'ServiceName': 'Amazon Personalize'},
              {'ServiceCode': 'pinpoint', 'ServiceName': 'Amazon Pinpoint'},
              {'ServiceCode': 'polly', 'ServiceName': 'Amazon Polly'},
              {'ServiceCode': 'profile',
               'ServiceName': 'Amazon Connect Customer Profiles'},
              {'ServiceCode': 'proton', 'ServiceName': 'AWS Proton'},
              {'ServiceCode': 'qldb', 'ServiceName': 'Amazon QLDB'},
              {'ServiceCode': 'quicksight', 'ServiceName': 'Amazon QuickSight'},
              {'ServiceCode': 'ram',
               'ServiceName': 'AWS Resource Access Manager'},
              {'ServiceCode': 'rds',
               'ServiceName': 'Amazon Relational Database Service (Amazon '
                              'RDS)'},
              {'ServiceCode': 'redshift', 'ServiceName': 'Amazon Redshift'},
              {'ServiceCode': 'rekognition',
               'ServiceName': 'Amazon Rekognition'},
              {'ServiceCode': 'resource-groups',
               'ServiceName': 'AWS Resource Groups'},
              {'ServiceCode': 'robomaker', 'ServiceName': 'AWS RoboMaker'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '2065',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:25 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'route53', 'ServiceName': 'Amazon Route 53'},
              {'ServiceCode': 'route53resolver',
               'ServiceName': 'Route 53 Resolver'},
              {'ServiceCode': 's3',
               'ServiceName': 'Amazon Simple Storage Service (Amazon S3)'},
              {'ServiceCode': 's3-outposts', 'ServiceName': 'AWS S3 Outposts'},
              {'ServiceCode': 'schemas',
               'ServiceName': 'Amazon EventBridge Schema Registry'},
              {'ServiceCode': 'secretsmanager',
               'ServiceName': 'AWS Secrets Manager'},
              {'ServiceCode': 'securityhub', 'ServiceName': 'AWS Security Hub'},
              {'ServiceCode': 'serverlessrepo',
               'ServiceName': 'AWS Serverless Application Repository'},
              {'ServiceCode': 'servicecatalog',
               'ServiceName': 'AWS Service Catalog'},
              {'ServiceCode': 'servicequotas', 'ServiceName': 'Service Quotas'},
              {'ServiceCode': 'ses',
               'ServiceName': 'Amazon Simple Email Service(Amazon SES)'},
              {'ServiceCode': 'shield', 'ServiceName': 'AWS Shield Advanced'},
              {'ServiceCode': 'signer', 'ServiceName': 'AWS Signer'},
              {'ServiceCode': 'sms',
               'ServiceName': 'AWS Server Migration Service'},
              {'ServiceCode': 'snow-device-management',
               'ServiceName': 'AWS Snow Device Management'},
              {'ServiceCode': 'snowball', 'ServiceName': 'AWS Snow Family'},
              {'ServiceCode': 'sns',
               'ServiceName': 'Amazon Simple Notification Service (Amazon '
                              'SNS)'},
              {'ServiceCode': 'sqs',
               'ServiceName': 'Amazon Simple Queue Service (Amazon SQS)'},
              {'ServiceCode': 'ssm', 'ServiceName': 'AWS Systems Manager'},
              {'ServiceCode': 'ssm-contacts',
               'ServiceName': 'AWS Systems Manager Incident Manager Contacts'}]}
{'NextToken': 'UFQCQUFBQUFBRUNBZ0I0eFRmc0hCK2p5R1lFbE5ncmV0a0FJWGZwYTRnd2VYUEh6S1VzR2ZGRGpwNEJ長いので中略',
 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '1904',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:25 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': [{'ServiceCode': 'ssm-incidents',
               'ServiceName': 'AWS Systems Manager Incident Manager'},
              {'ServiceCode': 'sso', 'ServiceName': 'AWS Single Sign-On (SSO)'},
              {'ServiceCode': 'states', 'ServiceName': 'AWS Step Functions'},
              {'ServiceCode': 'storagegateway',
               'ServiceName': 'AWS Storage Gateway'},
              {'ServiceCode': 'sumerian', 'ServiceName': 'Amazon Sumerian'},
              {'ServiceCode': 'support', 'ServiceName': 'AWS Support'},
              {'ServiceCode': 'swf',
               'ServiceName': 'Amazon Simple Workflow Service'},
              {'ServiceCode': 'textract', 'ServiceName': 'Amazon Textract'},
              {'ServiceCode': 'timestream', 'ServiceName': 'Amazon Timestream'},
              {'ServiceCode': 'transcribe', 'ServiceName': 'Amazon Transcribe'},
              {'ServiceCode': 'transfer', 'ServiceName': 'AWS Transfer Family'},
              {'ServiceCode': 'translate', 'ServiceName': 'Amazon Translate'},
              {'ServiceCode': 'vmimportexport',
               'ServiceName': 'EC2 VM Import/Export'},
              {'ServiceCode': 'vpc',
               'ServiceName': 'Amazon Virtual Private Cloud (Amazon VPC)'},
              {'ServiceCode': 'waf', 'ServiceName': 'AWS WAF'},
              {'ServiceCode': 'waf-regional',
               'ServiceName': 'AWS WAF Regional'},
              {'ServiceCode': 'wafv2', 'ServiceName': 'AWS WAF V2'},
              {'ServiceCode': 'wam',
               'ServiceName': 'Amazon WorkSpaces Application Manager'},
              {'ServiceCode': 'workspaces', 'ServiceName': 'Amazon WorkSpaces'},
              {'ServiceCode': 'xray', 'ServiceName': 'AWS X-Ray'}]}
{'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '15',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Sat, 02 Oct 2021 03:33:26 GMT',
                                      'x-amzn-requestid': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
                      'RetryAttempts': 0},
 'Services': []}
>>> 

今まで1回1回やらなきゃいけなかったことが、連なって後ろまで出力することが出来た。

ちなみにWhileループでも同じことが出来る。その場合は変数responseに'NextToken'がある間は後続処理を実行という形で書く。

最初は「NextTokenってなんだよ!どこにあんだよ!」とプリプリしていたけど、使ってみると「なるほど」となってきた。

Discussion