AWS Lambda Powertools Pythonをまとめてみた。AWS Lambda Powertools Python 〜概要編〜

# AWS Lambda Powertools Pythonとは
[AWS Lambda Powertools Python](https://awslabs.github.io/aws-lambda-powertools-python/latest/) は、AWS Lambda関数用のユーティリティースイートで、トレース、構造化ロギング、カスタムメトリックスなどのベストプラクティスの導入を容易にします。 AWS Lambda Powertools (python) は、AWS Lambda関数の実行環境とサポートされているランタイム専用に最適化されています。Core Utilitiesの使い方については、こちらの[Blog](https://aws.amazon.com/jp/blogs/opensource/simplifying-serverless-best-practices-with-lambda-powertools/)にも書かれています。

## インストール方法
Powertoolsは以下の方法で利用可能です。

- Lambda Layer: arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPython:4
- PyPi: pip install aws-lambda-powertools

### Lambda Layer
Lambda Layer は.zip ファイルアーカイブで、追加のコード、依存パッケージ、データ、または設定ファイルを含めることができます。Layerはコードの共有と責任の分離を促進し、ビジネスロジックの記述をより早く実装し、イテレーションを回すことができます。

| Region | Layer ARN |
|:-:|:-:|
|us-east-1|arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPython:4  |
|us-east-2|arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPython:4  |
|us-west-1|arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|us-west-2|arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|ap-south-1|arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|ap-northeast-1|arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|ap-northeast-2|arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|ap-northeast-3|arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|ap-southeast-1|arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|ap-southeast-2|arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|eu-central-1|arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|eu-west-1|arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|eu-west-2|arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|eu-west-3|arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|eu-north-1|arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|ca-central-1|arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |
|sa-east-1|arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPython:4   |

#### SAMによる指定
AWS Serverless Application Model (SAM) を利用して組み込む場合は、以下のように指定します。

``` YAML
MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
        Layers:
            - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:4
```
:::note warn
注意：コンテナイメージデプロイメント（OCI）やインラインLambda関数はLambda Layerをサポートしていません。
:::

### Serverless Application Repository
Serverless Application Repository (SAR) アプリケーションはあなたのアカウントの指定したリージョンにLambda Layerを含むCloudFormationスタックをデプロイします。パブリックなLayer ARNオプションと比べてより多くのステップがありますが、利用したいセマンティックバージョンを指定できるメリットがあります。

| App | ARN | 説明 |
|:-:|:-:|:-:|
|[aws-lambda-powertools-python-layer](https://serverlessrepo.aws.amazon.com/applications/eu-west-1/057560766410/aws-lambda-powertools-python-layer)|arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer|Coreの依存ライブラリのみを含む。ほぼすべてのユーティリティーをカバー。|
|[aws-lambda-powertools-python-layer-extras](https://serverlessrepo.aws.amazon.com/applications/eu-west-1/057560766410/aws-lambda-powertools-python-layer-extras)|arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer-extras |Coreの依存ライブラリとParserで利用しているPaydanticなどの依存ライブラリを含む。|

:::note warn
注意：Layer-extrasはPython 3.6ランタイムをサポートしていません。このLayerはすべての追加の依存ライブラリを含んでいます。Zip状態で22.4MB、解凍後は155MBになります。
:::

:::note info
共有Lambda Layerスタックを作成し、別のアカウントレベルのLayerスタックと共通に利用できます。
:::

SAMを利用する場合、このSARアプリケーションを共有Layerスタックの一部として、特定のセマンティックバージョンにロックして含むことができます。一度デプロイすると、それがデプロイされたアカウントにまたがって利用可能になります。

``` YAML
AwsLambdaPowertoolsPythonLayer:
    Type: AWS::Serverless::Application
    Properties:
        Location:
            ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
            SemanticVersion: 1.22.0 # change to latest semantic version available in SAR

MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
        Layers:
            # fetch Layer ARN from SAR App stack output
            - !GetAtt AwsLambdaPowertoolsPythonLayer.Outputs.LayerVersionArn
```

SAR APIを通じて利用可能なバージョンを取得することができます。

```shell
aws serverlessrepo list-application-versions \
    --application-id arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
```

以下にAWS Lambda Powertools Pythonに含まれている機能（Core UtilitiesとUtilities）を簡単に紹介します。

# Core Utilities
Core Utilitiesには、Tracer、Logger、Metrics、Event Handlerが含まれます。

## Tracer
Tracerは、AWS X-Ray Python SDKの薄いラッパーです。


- アノテーションとしてコールドスタート、メタデータとしてレスポンスまたは完全な例外を自動的にキャプチャー
- AWS Lambda環境で実行していないときは自動的に無効化
- 非同期メソッド、ジェネレータ、コンテキストマネージャのトレースをサポート
- AWS X-Rayによる自動パッチサポートモジュール

## Logger
Loggerは構造化されたJSONの出力を行うロガーを提供します。

- Lambdaコンテキスト、コールドスタート、JSONで構造化されたロギング出力のキーフィールドをキャプチャー
- 設定によりLambdaイベントをログに記録 (デフォルトでは無効)
- ログサンプリングはリクエストのパーセンテージのDEBUGログレベルを有効化 (デフォルトでは無効)
- 任意の時点で構造化ログに追加のキーを追加する


## Metrics
Metricsは、Amazon CloudWatch Embedded Metrics Format (EMF) に従ってメトリクスを標準出力にロギングすることで、カスタムメトリクスを非同期に作成します。

- 単一の CloudWatch EMFオブジェクト (大きなJSON BLOB) を使用して最大100個のメトリクスを集約
- 一般的なメトリック定義の間違い（メトリック単位、値、最大ディメンジョン、最大メトリクスなど）に対する検証
- CloudWatchサービスによってメトリクスは非同期に作成、カスタムスタックは不要
- 異なるディメンションに1回限りのメトリクスを作成するContext Manager


## Event Handler
Event HandlerとしてAppSyncとAPI Gateway用のイベントハンドラを提供します。

### Appsync
AppSync Direct Lambda ResolverとAmplify GraphQL Transformerのイベントハンドラを提供します。

- APIの引数を自動的にパースして関数の引数にセット
- GraphQLのフィールド名と厳密に一致するもののみか、すべての値を関数へ渡すかを選択可能
- リゾルバとアイデンティティ情報へアクセスするためのData classes utilitiesとの統合
- Direct Lambda ResolverとAmplify GraphQL Transformerの@functionディレクティブの両方で動作
- Python 3.8以降の関数で非同期とジェネレータをサポート

 
### API Gateway
Amazon API Gateway REST/HTTP APIとApplication Load Balancer(ALB)のためのイベントハンドラを提供します。

- API Gateway REST/HTTP APIとALBのためのボイラープレートを削減するための軽量なルーティング
- CORS、バイナリ、Gzip圧縮のシームレスなサポート
- イベントとアイデンティティ情報へ容易にアクセスするためのData classes utilitiesとの統合
- DecimalのJSONエンコーディングのビルトインサポート
- 動的path表記のサポート
- 複数ファイルを跨ったハンドラの分割を許可するルーティング



#Utilities
Utilitiesには、Middleware factory、Parameters、SQS Batch Processing、Typing、Validation、Event Source data Classes、Parser、Idempotency、Feature flags、JMESPath Functionsが含まれます。

## Middleware factory
Middleware factoryは個々のLambdaの実行の前後に同期的にロジックを実行するための独自のミドルウェアを作成するためのデコレーターファクトリを提供します。

- 前後のロジックの実行と例外のハンドル
- リクエストが発生した時のミドルウェアのトレース

## Parameters
parametersユーティリティーはひとつ、または複数のパラメータ値をAWS Systems Manager Parameter Store、AWS Secrets Manager、AWS AppConfig、Amazon DynamoDB、または独自設定から取得する高レベルの関数を提供します。

- ひとつ、または複数のパラメーターを下位のプロバイダから取得
- 設定された時間パラメータの値をキャッシュ（デフォルトは5秒）
- JSONまたはbase64エンコード文字列のパラメータ値を変換
- 独自のパラメータストアプロバイダを持ち込み可能


## SQS Batch Processing
SQS batch processingはSQSからのメッセージのバッチ処理中に部分的な失敗を処理する方法を提供します。

- 処理が成功したメッセージがSQSに戻されるのを防ぐ
- バッチの個別のメッセージ処理のためのシンプルなインターフェイス
- ベースクラスを利用して独自のバッチ処理を構築可能

## Typing
typingユーティリティーはIDEの型ヒントの提供による開発容易性に利用可能な静的型付けクラスを提供します。
LambdaContext typingは、一般的にLambda関数のためのハンドラメソッド内で利用されます。

## Validation
validationユーティリティーはイベントとレスポンスのためのJSONスキーマバリデーションを提供します。検証する前にイベントをアンラップするためのJMESPathをサポートします。

- 入力イベントとレスポンスの検証
- 検証を適用する前にイベントをアンラップするJMESPathをサポート
- 良く知られたイベントソースのペイロードをアンラップするためのビルトインのエンベロープ

## Event Source Data Classes
Event Source Data Classesユーティリティーは自己記述型のLambdaイベントソースクラスを提供します。

- 一般的なイベント型に対する型ヒントとコード補完
- ネストされたフィールドのデコード/デシリアライズのためのヘルパー関数
- イベントスキーマ内に含まれるフィールドのためのコメント文字列

## Parser
Parserユーティリティーは[Pydantic](https://pydantic-docs.helpmanual.io/)を利用したデータのパースとディープバリデーションを提供します。

- ピュアPythonクラスのデータ定義、データのパース、検証と展開
- アンラップ、拡張、一般的なイベントソースペイロードのビルトインエンベロープ
- ユーザーフレンドリーなエラーと共に実行時に型ヒントを強制

## Idempotency
Idempotencyユーティリティーは安全なリトライを実行するための冪等性操作へLambda関数を変換するシンプルなソリューションを提供します。

- 一定時間内に同一イベントのペイロードに対して1回以上のLambdaハンドラの実行を防ぐ
- 同じペイロードを伴う呼び出しに対して同じ結果をLambdaハンドラが返却することを保証
- JMESPath表現を利用して冪等性のキーとしてイベントのサブセットを選択
- 重複と考えられる同じペイロードのレコードに対するタイムウィンドウをセット

## Feature flags
feature flagsユーティリティーは、ひとつまたは複数のフィーチャーが入力に基づいて有効化される方法を定義するためのシンプルなルールエンジンを提供します。

- フィーチャーをいつ有効にするかを動的に決定するためのシンプルなフィーチャーフラグを定義
- 与えられたアプリケーションコンテキストのために有効化する、ひとつまたは全てのフィーチャーフラグを取得
- ルールなしにシンプルにフィーチャーをオン、オフする静的なフィーチャーフラグのサポート

## JMESPath Functions
ビルトインのJMESPath関数は、Lambda関数の一般的なエンコード済みJSONペイロードを容易にデシリアライズします。

- JSON文字列、base64、圧縮されたデータからJSONをデシリアライズ
- 展開と再起的なデータの組み合わせのためにJMESPathを使用


# まとめ
いかがでしたでしょうか。AWS Lambda Powertools Python 〜概要編〜では、AWS Lambda Powertools Pythonの概要、インストール方法、提供されるユーティリティー群について簡単に紹介しました。~~次回以降では、個々のユーティリティーについてより詳しく紹介する予定です。どうぞお楽しみに。~~

:::note info
2022.04.12追記：AWS Lambda Powertools Pythonのユーティリティーについては、aws builders.flashで連載することになりました。ぜひこちらもご覧ください。
:::

[AWS Lambda Powertools Python入門 第1回](https://aws.amazon.com/jp/builders-flash/202203/lambda-powertools-python-1/)
[AWS Lambda Powertools Python入門 第2回 Tracer Utility](https://aws.amazon.com/jp/builders-flash/202204/lambda-powertools-python-2/)

本投稿は、個人の意見で、所属する企業や団体は関係ありません。
また掲載しているサンプルプログラム等の動作に関しても一切保証しておりません。