

# Python による Lambda 関数の構築
<a name="lambda-python"></a>

AWS Lambda で Python コードを実行できます。Lambda は、コードを実行してイベントを処理する Python 用の[ランタイム](lambda-runtimes.md)を提供します。コードは、管理している AWS Identity and Access Management (IAM) ロールの認証情報により、SDK for Python (Boto3) を備えた環境で実行されます。Python ランタイムに含まれている SDK バージョンの詳細については、「[ランタイムに含まれる SDK バージョン](#python-sdk-included)」を参照してください。

Lambda は、以下の Python ランタイムをサポートしています。


| 名前 | 識別子 | オペレーティングシステム | 廃止日 | 関数の作成をブロックする | 関数の更新をブロックする | 
| --- | --- | --- | --- | --- | --- | 
|  Python 3.14  |  `python3.14`  |  Amazon Linux 2023  |   2029 年 6 月 30 日   |   2029 年 7 月 31 日   |   2029 年 8 月 31 日   | 
|  Python 3.13  |  `python3.13`  |  Amazon Linux 2023  |   2029 年 6 月 30 日   |   2029 年 7 月 31 日   |   2029 年 8 月 31 日   | 
|  Python 3.12  |  `python3.12`  |  Amazon Linux 2023  |   2028 年 10 月 31 日   |   2028 年 11 月 30 日   |   2029 年 1 月 10 日   | 
|  Python 3.11  |  `python3.11`  |  Amazon Linux 2  |   2027 年 6 月 30 日   |   2027 年 7 月 31 日   |   2027 年 8 月 31 日   | 
|  Python 3.10  |  `python3.10`  |  Amazon Linux 2  |   2026 年 10 月 31 日   |   2026 年 11 月 30 日   |   2027 年 1 月 15 日   | 

**Python 関数を作成するには**

1. [Lambda コンソール](https://console.aws.amazon.com/lambda)を開きます。

1. [**Create function**] (関数の作成) をクリックします。

1. 以下の設定を行います。
   + **[関数名]**: 関数名を入力します。
   + **[ランタイム]**: **[Python 3.14]** を選択します。

1. [**関数の作成**] を選択してください。

コンソールで、`lambda_function` という名前の単一のソースファイルを含む Lambda 関数が作成されます。このファイルを編集し、組み込みのコードエディタでファイルをさらに追加することができます。**[DEPLOY]** セクションで **[デプロイ]** を選択して関数のコードを更新します。次に、コードを実行するには、**[TEST EVENTS]** セクションで **[テストイベントを作成]** を選択します。

Lambda 関数には CloudWatch Logs ロググループが付属しています。関数のランタイムは、各呼び出しに関する詳細を CloudWatch Logs に送信します。これは呼び出し時に、任意の[関数が出力するログ](python-logging.md)を中継します。関数がエラーを返す場合、Lambda はエラー形式を整え、それを呼び出し元に返します。

**Topics**
+ [ランタイムに含まれる SDK バージョン](#python-sdk-included)
+ [無効な Python 機能](#python-disabled-features)
+ [レスポンスの形式](#python-response-format)
+ [拡張機能の正常なシャットダウン](#python-graceful-shutdown)
+ [Python の Lambda 関数ハンドラーの定義](python-handler.md)
+ [Python Lambda 関数で .zip ファイルアーカイブを使用する](python-package.md)
+ [コンテナイメージで Python Lambda 関数をデプロイする](python-image.md)
+ [Python Lambda 関数にレイヤーを使用する](python-layers.md)
+ [Lambda コンテキストオブジェクトを使用して Python 関数の情報を取得する](python-context.md)
+ [Python Lambda 関数のログ記録とモニタリング](python-logging.md)
+ [Python での AWS Lambda 関数テスト](python-testing.md)
+ [AWS Lambda での Python コードの作成](python-tracing.md)

## ランタイムに含まれる SDK バージョン
<a name="python-sdk-included"></a>

Python ランタイムに含まれる AWS SDK のバージョンは、ランタイムバージョンと AWS リージョン によって異なります。使用しているランタイムに含まれている SDK のバージョンを確認するには、次のコードを使用して Lambda 関数を作成します。

```
import boto3
import botocore

def lambda_handler(event, context):
   print(f'boto3 version: {boto3.__version__}')
   print(f'botocore version: {botocore.__version__}')
```

## 無効な Python 機能
<a name="python-disabled-features"></a>

次のテーブルでは、Lambda マネージドランタイムおよび Python のコンテナベースイメージで無効になっている Python の機能が示されます。これらの機能は Python ランタイムの実行可能ファイルがコンパイルされるときに有効にする必要があり、実行時間フラグを使用して有効にすることはできません。Lambda でこれらの機能を使用するには、[コンテナイメージ](python-image.md#python-image-clients)または[カスタムランタイム](runtimes-custom.md)を使用し、これらの機能を有効にして独自の Python ランタイムビルドをデプロイできます。


| Python 機能 | 影響を受ける Python バージョン | ステータス | 
| --- | --- | --- | 
| Just-in-Time (JIT) コンパイラ | Python 3.13 以降 | JIT コンパイラは実験的であり、本番稼働ワークロードには推奨されません。したがって、Lambda Python ランタイムでは無効になっています。 | 
| フリースレッディング | Python 3.13 以降 | シングルスレッドコードによるパフォーマンスへの影響により、Lambda Python ビルドではフリースレッド (グローバルインタープリタロックを無効にするオプション) が無効になっています。 | 

## レスポンスの形式
<a name="python-response-format"></a>

Python 3.12 以降の Python ランタイムでは、関数は JSON レスポンスの一部としてユニコード文字を返します。以前の Python ランタイムは、レスポンス内の Unicode 文字のエスケープシーケンスを返していました。例えば、Python 3.11 では、"こんにちは" のようなユニコード文字列を返すと、ユニコード文字はエスケープされ、"\$1u3053\$1u3093\$1u306b\$1u3061\$1u306f" が返されます。Python 3.12 ランタイムは本来の "こんにちは" を返します。

Unicode レスポンスを使用すると、Lambda レスポンスのサイズが小さくなるため、同期関数の 6 MB の最大ペイロードサイズに大きなレスポンスを簡単に収めることができます。前の例では、エスケープされたバージョンは 32 バイトですが、Unicode 文字列では 17 バイトです。

Python 3.12 以降の Python ランタイムにアップグレードする場合、新しい応答形式に合わせてコードを調整する必要がある場合があります。呼び出し側が Unicode のエスケープを想定している場合、戻り値関数にコードを追加して Unicode を手動でエスケープするか、Unicode の戻り値を処理するように呼び出し側を調整する必要があります。

## 拡張機能の正常なシャットダウン
<a name="python-graceful-shutdown"></a>

Python 3.12 以降の Python ランタイムでは、[外部拡張機能](lambda-extensions.md)を含む関数のグレースフルシャットダウン機能が改善されています。Lambda は、実行環境をシャットダウンするときに、ランタイムに `SIGTERM` シグナルを送信してから、登録された各外部拡張機能に `SHUTDOWN` イベントを送信します。Lambda 関数で `SIGTERM` シグナルをキャッチし、その関数によって作成されたデータベース接続などのリソースをクリーンアップできます。

実行環境のライフサイクルの詳細については、「[Lambda 実行環境のライフサイクルの概要](lambda-runtime-environment.md)」を参照してください。拡張機能でグレースフルシャットダウンを使用する方法の例については、「[AWS Samples GitHub リポジトリ](https://github.com/aws-samples/graceful-shutdown-with-aws-lambda)」を参照してください。

# Python の Lambda 関数ハンドラーの定義
<a name="python-handler"></a>

Lambda 関数*ハンドラー*は、イベントを処理する関数コード内のメソッドです。関数が呼び出されると、Lambda はハンドラーメソッドを実行します。関数は、ハンドラーが応答を返すか、終了するか、タイムアウトするまで実行されます。

このページでは、命名規則、有効なハンドラー署名、コードのベストプラクティスなど、Python で Lambda 関数ハンドラーを操作する方法について説明します。このページには、注文に関する情報を取得し、テキストファイル受信を生成し、このファイルを Amazon Simple Storage Service (Amazon S3) バケットに配置する Python Lambda 関数の例も含まれています。

**Topics**
+ [Python Lambda 関数のコードの例](#python-handler-example)
+ [ハンドラーの命名規則](#python-handler-naming)
+ [Lambda のイベントオブジェクトの使用](#python-handler-event)
+ [Lambda コンテキストオブジェクトへのアクセスと使用](#python-handler-context)
+ [Python ハンドラーの有効なハンドラー署名](#python-handler-signature)
+ [値の返し](#python-handler-return)
+ [ハンドラーでの AWS SDK for Python (Boto3) の使用](#python-handler-sdk)
+ [環境変数にアクセスする](#python-handler-env-vars)
+ [Python Lambda 関数のベストプラクティスに従ってください。](#python-handler-best-practices)

## Python Lambda 関数のコードの例
<a name="python-handler-example"></a>

以下の Python Lambda 関数 Lambda 関数コードの例では、注文に関する情報を取得し、テキストファイル受信を生成し、このファイルを Amazon S3 バケットに配置します。

**Example Python Lambda 関数**  

```
import json
import os
import logging
import boto3

# Initialize the S3 client outside of the handler
s3_client = boto3.client('s3')

# Initialize the logger
logger = logging.getLogger()
logger.setLevel("INFO")

def upload_receipt_to_s3(bucket_name, key, receipt_content):
    """Helper function to upload receipt to S3"""
    
    try:
        s3_client.put_object(
            Bucket=bucket_name,
            Key=key,
            Body=receipt_content
        )
    except Exception as e:
        logger.error(f"Failed to upload receipt to S3: {str(e)}")
        raise

def lambda_handler(event, context):
    """
    Main Lambda handler function
    Parameters:
        event: Dict containing the Lambda function event data
        context: Lambda runtime context
    Returns:
        Dict containing status message
    """
    try:
        # Parse the input event
        order_id = event['Order_id']
        amount = event['Amount']
        item = event['Item']
        
        # Access environment variables
        bucket_name = os.environ.get('RECEIPT_BUCKET')
        if not bucket_name:
            raise ValueError("Missing required environment variable RECEIPT_BUCKET")

        # Create the receipt content and key destination
        receipt_content = (
            f"OrderID: {order_id}\n"
            f"Amount: ${amount}\n"
            f"Item: {item}"
        )
        key = f"receipts/{order_id}.txt"

        # Upload the receipt to S3
        upload_receipt_to_s3(bucket_name, key, receipt_content)

        logger.info(f"Successfully processed order {order_id} and stored receipt in S3 bucket {bucket_name}")
        
        return {
            "statusCode": 200,
            "message": "Receipt processed successfully"
        }

    except Exception as e:
        logger.error(f"Error processing order: {str(e)}")
        raise
```

この ファイルには以下のコードのセクションが含まれます:
+ `import` ブロック: このブロックを使用して、Lambda 関数に必要なライブラリを含めます。
+ SDK クライアントとロガーのグローバル初期化: ハンドラーの外側に初期化コードを含めると、[実行環境](lambda-runtime-environment.md)の再利用を活用して関数のパフォーマンスが向上します。詳細については、「[Python Lambda 関数のベストプラクティスに従ってください。](#python-handler-best-practices)」を参照してください。
+ `def upload_receipt_to_s3(bucket_name, key, receipt_content):` これは、メイン `lambda_handler` 関数によって呼び出されるヘルパー関数です。
+ `def lambda_handler(event, context):`: これは**メインハンドラー関数**で、メインアプリケーションロジックが含まれています。Lambda が関数ハンドラーを呼び出すと、[Lambda ランタイム](concepts-basics.md#gettingstarted-concepts-runtime)は 2 つの引数を関数に渡します。1 つは関数が処理するデータを含む[イベントオブジェクト](#python-handler-event)で、もう 1 つは関数に関する情報が含まれる[コンテキストオブジェクト](#python-handler-context)です。

## ハンドラーの命名規則
<a name="python-handler-naming"></a>

Lambda 関数の作成時に定義される関数ハンドラー名は、以下から取得されます。
+ Lambda ハンドラー関数が配置されているファイルの名前
+ Python ハンドラー関数の名前

上記の例では、ファイルが `lambda_function.py` という名前の場合、ハンドラーは `lambda_function.lambda_handler` として指定されます。これは、Lambda コンソールを使用して作成する関数にデフォルトで付けられるハンドラー名です。

異なるファイル名または関数ハンドラー名を使用してコンソールで関数を作成する場合は、デフォルトのハンドラー名を編集する必要があります。

**関数ハンドラー名を変更するには (コンソール)**

1. Lambda コンソールの [[関数]](https://console.aws.amazon.com/lambda/home#/functions) ページを開き、関数を選択します。

1. **[コード]** タブを選択します。

1. **[ランタイム設定]** ペインまでスクロールして、**[編集]** を選択します。

1. **[ハンドラー]** には、関数ハンドラーの新しい名前を入力します。

1. **[保存]** を選択します。

## Lambda のイベントオブジェクトの使用
<a name="python-handler-event"></a>

Lambda が関数を呼び出すとき、[イベントオブジェクト](concepts-basics.md#gettingstarted-concepts-event)引数が関数ハンドラーに渡されます。JSON オブジェクトは、Lambda 関数で最も一般的なイベント形式です。前のセクションのコード例では、関数は次の形式の入力を期待します。

```
{
    "Order_id": "12345",
    "Amount": 199.99,
    "Item": "Wireless Headphones"
}
```

関数が他の AWS のサービス によって呼び出された場合、入力イベントも JSON オブジェクトです。イベントオブジェクトの具体的な形式は、関数を呼び出すサービスによって異なります。特定のサービスのイベント形式を確認するには、[他の AWS サービスからのイベントを使用した Lambda の呼び出し](lambda-services.md) 章の該当するページを参照してください。

入力イベントが JSON オブジェクトの形式の場合、Lambda ランタイムはオブジェクトを Python 辞書型に変換します。入力 JSON の値をコードの変数に割り当てるには、コード例のように標準の Python の辞書メソッドを使用します。

また、関数に JSON 配列や他の有効な JSON データ型をデータとして渡すこともできます。次の表は、Python ランタイムが JSON 型を変換する際の対応関係を示します。


| JSON データ型 | Python データ型 | 
| --- | --- | 
| オブジェクト | 辞書 (dict) | 
| 配列 | リスト (list) | 
| 数値 | 整数 (int) または浮動小数点数 (float） | 
| 文字列 | 文字列 (str) | 
| ブール値 | ブール値 (bool) | 
| null | NoneType (NoneType） | 

## Lambda コンテキストオブジェクトへのアクセスと使用
<a name="python-handler-context"></a>

Lambda コンテキストオブジェクトには、関数の呼び出しと実行環境に関する情報が含まれています。Lambda は、関数が呼び出されると、自動的にコンテキストオブジェクトを渡します。モニタリング目的として、コンテキストオブジェクトを使用して関数の呼び出しに関する情報を出力できます。

コンテキストオブジェクトは、[Lambda ランタイムインターフェイスクライアント](https://github.com/aws/aws-lambda-python-runtime-interface-client/blob/main/awslambdaric/lambda_context.py)で定義された Python クラスです。コンテキストオブジェクトのプロパティのいずれかの値を返すには、コンテキストオブジェクトの対応するメソッドを使用します。例えば、次のコードスニペットは、 `aws_request_id` プロパティ (呼び出しリクエストの識別子) の値を `request` という名前の変数に割り当てます。

```
request = context.aws_request_id
```

Lambda コンテキストオブジェクトの使用方法の詳細と、使用可能なメソッドとプロパティの完全なリストについては、「[Lambda コンテキストオブジェクトを使用して Python 関数の情報を取得する](python-context.md)」を参照してください。

## Python ハンドラーの有効なハンドラー署名
<a name="python-handler-signature"></a>

Python でハンドラー関数を定義する場合、関数は 2 つの引数を取るようにしてください。これらの引数のうち、1 番目の引数は Lambda [イベントオブジェクト](#python-handler-event)で、2 番目の引数は Lambda [コンテキストオブジェクト](#python-handler-context)です。慣例により、これらの入力引数には通常 `event` と `context` という名前が付けられますが、任意の名前を付けることができます。入力引数を １ つでハンドラー関数を宣言すると、Lambda は関数の実行をしようとするとエラーになります。Python でハンドラー関数を宣言する最も一般的な方法を次に示します。

```
def lambda_handler(event, context):
```

次の例に示すように、関数の宣言で Python の型ヒントを使用することもできます。

```
from typing import Dict, Any
      
def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
```

他の `aws-lambda-typing` によって生成されたイベントやコンテキストオブジェクトに特定の AWS のサービス 型を使用するには、AWS パッケージを関数のデプロイメントパッケージに追加します。このライブラリは、`pip install aws-lambda-typing` を実行して開発環境にインストールできます。次のコードスニペットは、AWS に固有の型ヒントの使用方法を示しています。この例では、期待されるイベントは Amazon S3 イベントです。

```
from aws_lambda_typing.events import S3Event
from aws_lambda_typing.context import Context
from typing import Dict, Any

def lambda_handler(event: S3Event, context: Context) -> Dict[str, Any]:
```

ハンドラー `async` 関数に Python 関数型を使用することはできません。

## 値の返し
<a name="python-handler-return"></a>

オプションで、ハンドラーは値を返すことができますが、その値はJSONにシリアライズできるものでなければなりません。一般的な戻り値の型には、 `dict`、`list`、`str`、`int`、`float`、`bool` があります。

戻り値に何が起きるかは、[呼び出しの種類](lambda-invocation.md)と呼び出した[サービス](lambda-services.md) に応じて変わります。例:
+ `RequestResponse` 呼び出しタイプを使用して [Lambda 関数を同期的に呼び出す](invocation-sync.md)場合、Lambda は Python 関数の呼び出しの結果を、Lambda 関数を呼び出したクライアントに返します (呼び出しリクエストに対する HTTP レスポンスでは、JSON にシリアル化されます)。たとえば、AWS Lambda のコンソールは `RequestResponse` の呼び出しタイプを使用するため、コンソールを使用して関数を呼び出すと、コンソールに戻り値が表示されます。
+ ハンドラーから `json.dumps` でシリアル化できないオブジェクトが返された場合、ランタイムはエラーを返します。
+ `None` ステートメントを指定しなかった場合の Python 関数の暗黙の動作と同じように、ハンドラーが `return` を返した場合、ランタイムは `null` を返します。
+ 「`Event`」 呼び出しタイプ ([非同期呼び出し](invocation-async.md)) を使用する場合、値は破棄されます。

サンプルコードでは、ハンドラーは次の Python の辞書を返します。

```
{
  "statusCode": 200,
  "message": "Receipt processed successfully"
}
```

Lambda ランタイムはこの辞書をシリアル化し、関数を呼び出したクライアントに JSON 文字列として返します。

**注記**  
Python 3.9 以降のリリースでは、Lambda はエラーの応答時に呼び出しの requestId を含めます。

## ハンドラーでの AWS SDK for Python (Boto3) の使用
<a name="python-handler-sdk"></a>

多くの場合、Lambda 関数を使用して、他の AWS のサービス やリソースとやり取りしたりします。これらのリソースとインターフェイスする最も簡単な方法は、AWS SDK for Python (Boto3) を使用することです。[サポートされているすべての Lambda Python ランタイム](lambda-runtimes.md#runtimes-supported)には、SDK for Python のバージョンが含まれています。ただし、コードが SDK の利用を必要とする場合、関数デプロイパッケージに SDK を含めることを強く推奨します。デプロイパッケージに SDK を含めると、依存関係を完全に制御でき、他のライブラリとのバージョン不整合の問題のリスクが軽減できます。詳細については、「[Python でのランタイム依存関係](python-package.md#python-package-dependencies)」および「[下位互換性](runtimes-update.md#runtime-update-compatibility)」を参照してください。

Lambda 関数で SDK for Python を使用するには、関数コードの先頭にある import ブロックに次のステートメントを追加します。

```
import boto3
```

`pip install` コマンドを使用して、`boto3` ライブラリを関数のデプロイメント パッケージに追加します。.zip デプロイパッケージに依存関係を追加する方法の詳細については、「[依存関係を含めて .zip デプロイパッケージを作成する](python-package.md#python-package-create-dependencies)」を参照してください。コンテナイメージとしてデプロイされた Lambda 関数への依存関係の追加の詳細については、「[ベースイメージからイメージを作成する](python-image.md#python-image-create)」または「[代替ベースイメージからイメージを作成する](python-image.md#python-alt-create)」を参照してください。

コードで `boto3` を使用する場合、クライアントを初期化するための認証情報を提供する必要はありません。例えば、サンプルコードでは、Amazon S3クライアントを初期化するために次のコード行を使用します。

```
# Initialize the S3 client outside of the handler
s3_client = boto3.client('s3')
```

Python では、Lambda が認証情報を使用して環境変数を自動的に作成します。`boto3` SDK は、初期化の際にこれらの認証情報に関して関数内の環境変数をチェックします。

## 環境変数にアクセスする
<a name="python-handler-env-vars"></a>

ハンドラーコードでは、`os.environ.get` メソッドを使用して[環境変数](configuration-envvars.md)を参照できます。このサンプルコードでは、以下のコード行を使用して、定義された `RECEIPT_BUCKET` 環境変数を参照します:

```
# Access environment variables
bucket_name = os.environ.get('RECEIPT_BUCKET')
```

コードの先頭にある import ブロックに `import os` ステートメントを含めることを忘れないでください。

## Python Lambda 関数のベストプラクティスに従ってください。
<a name="python-handler-best-practices"></a>

Lambda 関数をビルドするときは、次のリストのガイドラインに従って、コーディングのベストプラクティスを実行してください。
+ **Lambda ハンドラーをコアロジックから分離します。**これにより、関数の単体テストが実行しやすくなります。例えば、Python では次のようになります。

  ```
  def lambda_handler(event, context):
      foo = event['foo']
      bar = event['bar']      
      result = my_lambda_function(foo, bar)
  
  def my_lambda_function(foo, bar):
      // MyLambdaFunction logic here
  ```
+ **関数のデプロイパッケージ内で依存関係を制御します。**AWS Lambda 実行環境には多数のライブラリが含まれています。Node.js および Python ランタイムの場合、ライブラリには AWS SDK が含まれます。最新の機能やセキュリティ更新プログラムを有効にするために、Lambda はこれらのライブラリを定期的に更新します。この更新により、Lambda 関数の動作が微妙に変化する場合があります。関数で使用する依存関係を完全に制御するには、すべての依存関係をデプロイパッケージでパッケージングします。
+ **依存関係の複雑さを最小限に抑えます。**フレームワークを単純化して、[実行環境](lambda-runtime-environment.md)起動時のロードを高速化します。
+ **デプロイパッケージをランタイムに必要な最小限のサイズにします。**これにより、呼び出しに先立ってデプロイパッケージをダウンロードして解凍する所要時間が短縮されます。

**実行環境の再利用を活用して関数のパフォーマンスを向上させます。**関数ハンドラー外で SDK クライアントとデータベース接続を初期化し、静的なアセットを `/tmp` ディレクトリにローカルにキャッシュします。関数の同じインスタンスで処理された後続の呼び出しは、これらのリソースを再利用できます。これにより、関数の実行時間が短縮され、コストが節約されます。

呼び出し間でデータが漏れるのを防ぐため、実行環境を使用してセキュリティ上の懸念があるユーザーデータ、イベント、またはその他の情報を保存しないでください。関数がハンドラー内のメモリに保存できない変更可能な状態に依存している場合は、ユーザーごとに個別の関数または個別のバージョンの関数を作成することを検討してください。

**keep-alive ディレクティブを使用して永続的な接続を維持します。**Lambda は、時間の経過とともにアイドル状態の接続を消去します。関数を呼び出すときにアイドル状態の接続を再利用しようとすると、接続エラーが発生します。永続的な接続を維持するには、ランタイムに関連付けられている keep-alive ディレクティブを使用します。例については、「[Node.js で Keep-alive を使用して接続を再利用する](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)」を参照してください。

**[環境変数](configuration-envvars.md)を使用して、オペレーショナルパラメータを関数に渡します。**たとえば、Amazon S3 バケットに書き込む場合、書き込み先のバケット名はハードコーディングせずに、環境変数として設定します。

Lambda 関数では、**再帰呼び出しを使用しないでください**。関数が自身を呼び出すこともあれば、新たに開始されたプロセスで関数が再度呼び出される可能性もあります。これを行うと意図しないボリュームで関数が呼び出され、料金が急増する可能性があります。意図しない呼び出しがいくつも見つかった場合は、すぐに関数の予約済同時実行数を `0` に設定して、コードを更新している間のすべての関数の呼び出しをスロットリングします。

Lambda 関数コードで**文書化されていない非公開の API を使用しないでください**。AWS Lambda マネージドランタイムでは、Lambda が Lambda の内部 API にセキュリティと機能面の更新を定期的に適用します。これらの内部 API 更新には後方互換性がないことがあり、関数にこれらの非公開 API に対する依存関係がある場合、呼び出しの失敗などの意図しない結果につながります。公開されている API のリストについては、「[API リファレンス](https://docs.aws.amazon.com/lambda/latest/api/welcome.html)」を参照してください。

**冪等性コードを記述します。**関数の記述に冪等性コードを使用すると、重複するイベントが同じ方法で処理されるようになります。コードでは、イベントを適切に検証し、重複するイベントを適切に処理する必要があります。詳細については、「[Lambda 関数を冪等にするにはどうすればよいですか?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/)」を参照してください。

# Python Lambda 関数で .zip ファイルアーカイブを使用する
<a name="python-package"></a>

 AWS Lambda 関数のコードは、関数のハンドラーコードと、そのコードが依存するその他のパッケージやモジュールを含む .py ファイルで構成されています。この関数コードを Lambda にデプロイするには、*デプロイパッケージ*を使用します。このパッケージは、.zip ファイルアーカイブでもコンテナイメージでもかまいません。Python でコンテナイメージを使用する方法の詳細については、「[コンテナイメージで Python Lambda 関数をデプロイする](https://docs.aws.amazon.com/lambda/latest/dg/python-image.html)」を参照してください。

 .zip ファイルのデプロイパッケージを .zip ファイルアーカイブとして作成するには、コマンドラインツール用の組み込み .zip ファイルアーカイブユーティリティ、または他の .zip ファイルユーティリティ ([7zip](https://www.7-zip.org/download.html) など) を使用します。次のセクションに示す例では、Linux または macOS 環境でコマンドライン `zip` ツールを使用していることを前提としています。Windows で同じコマンドを使用するには、[Windows Subsystem for Linux をインストールして](https://docs.microsoft.com/en-us/windows/wsl/install-win10)、Windows 統合バージョンの Ubuntu と Bash を取得します 

 Lambda は POSIX ファイルアクセス許可を使用するため、.zip ファイルアーカイブを作成する前に、[デプロイパッケージフォルダのアクセス許可を設定する](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-deployment-package-errors/)ことが必要になる場合があります。

**Topics**
+ [Python でのランタイム依存関係](#python-package-dependencies)
+ [依存関係のない .zip デプロイパッケージを作成する](#python-package-create-no-dependencies)
+ [依存関係を含めて .zip デプロイパッケージを作成する](#python-package-create-dependencies)
+ [依存関係検索パスおよびランタイムを含むライブラリ](#python-package-searchpath)
+ [\$1\$1pycache\$1\$1 フォルダを使用する](#python-package-pycache)
+ [ネイティブライブラリとともに .zip デプロイパッケージを作成する](#python-package-native-libraries)
+ [.zip ファイルを使用した Python Lambda 関数の作成と更新](#python-package-create-update)

## Python でのランタイム依存関係
<a name="python-package-dependencies"></a>

Python ランタイムを使用する Lambda 関数の場合、依存関係には任意の Python パッケージまたはモジュールを使用できます。.zip アーカイブを使用して関数をデプロイするとき、関数コードでこれらの依存関係を .zip ファイルに追加するか、[Lambda レイヤー](chapter-layers.md) を使用できます。レイヤーは、追加のコードまたはその他のコンテンツを含むことができる個別の .zip ファイルです。Python で Lambda レイヤーの使用の詳細については、「[Python Lambda 関数にレイヤーを使用する](python-layers.md)」を参照してください。

Lambda Python ランタイムには、AWS SDK for Python (Boto3) とその依存関係が含まれます。独自の依存関係を追加できないデプロイシナリオでは、Lambda がランタイムに SDK を提供します。これらのシナリオには、組み込みのコードエディタを使用してコンソールで関数を作成することや、AWS Serverless Application Model (AWS SAM) または CloudFormation テンプレート内のインライン関数を使用することが含まれます。

Lambda は Python ランタイムのライブラリを定期的に更新して、最新の更新とセキュリティパッチを適用します。関数がランタイムに含まれている Boto3 SDK のバージョンを使用しているにも関わらず、デプロイパッケージに SDK の依存関係が含まれている場合、バージョンの不整合の問題が発生する可能性があります。たとえば、デプロイパッケージに SDK 依存関係 urllib3 が含まれる場合があります。Lambda がランタイムで SDK を更新すると、新しいバージョンのランタイムとデプロイパッケージの urllib3 のバージョンとの互換性の問題により、関数が失敗する可能性があります。

**重要**  
依存関係を完全に制御し、バージョンの不整合の問題を回避するには、Lambda ランタイムにそれらのバージョンが含まれていても、関数のすべての依存関係をデプロイパッケージに追加することをお勧めします。これには Boto3 SDK が含まれます。

使用しているランタイムに含まれている SDK for Python (Boto3) のバージョンを確認するには、「[ランタイムに含まれる SDK バージョン](lambda-python.md#python-sdk-included)」を参照してください。

 [AWS 責任分担モデル](https://docs.aws.amazon.com/whitepapers/latest/aws-risk-and-compliance/shared-responsibility-model.html)では、関数のデプロイパッケージに含まれる依存関係を管理する責任があります。これには、更新とセキュリティパッチの適用が含まれます。関数のデプロイパッケージ内の依存関係を更新するには、まず新しい .zip ファイルを作成し、そのファイルを Lambda にアップロードします。詳細については、「[依存関係を含めて .zip デプロイパッケージを作成する](#python-package-create-dependencies)」と「[.zip ファイルを使用した Python Lambda 関数の作成と更新](#python-package-create-update)」を参照してください。

## 依存関係のない .zip デプロイパッケージを作成する
<a name="python-package-create-no-dependencies"></a>

 関数コードに依存関係がない場合、.zip ファイルには関数のハンドラーコードを含む .py ファイルのみが含まれます。任意の zip ユーティリティを使用して、.py ファイルをルートとする .zip ファイルを作成します。.py ファイルが .zip ファイルのルートにない場合、Lambda はコードを実行できません。

 .zip ファイルをデプロイして新しい Lambda 関数を作成する方法の詳細、既存の Lambda 関数を更新する方法の詳細については、「[.zip ファイルを使用した Python Lambda 関数の作成と更新](#python-package-create-update)」を参照してください。

## 依存関係を含めて .zip デプロイパッケージを作成する
<a name="python-package-create-dependencies"></a>

 関数コードが追加のパッケージやモジュールに依存している場合、関数コードでこれらの依存関係を .zip ファイルに追加するか、[Lambda レイヤー](python-layers.md) を使用できます。このセクションでは、依存関係を .zip デプロイパッケージに含める方法について説明します。Lambda でコードを実行するには、ハンドラーコードとすべての関数の依存関係を含む.py ファイルを.zip ファイルのルートにインストールする必要があります。

 関数コードが `lambda_function.py` という名前のファイルに保存されているとします。次の CLI コマンドの例では、関数コードとその依存関係を格納している `my_deployment_package.zip` という名前の .zip ファイルを作成します。依存関係をプロジェクトディレクトリのフォルダに直接インストールすることも、Python 仮想環境を使用することもできます。

**デプロイパッケージ (プロジェクトディレクトリ) を作成するには**

1. `lambda_function.py` ソースコードファイルを含むプロジェクトディレクトリに移動します。この例では、ディレクトリ名は `my_function` です。

   ```
   cd my_function
   ```

1. 依存関係をインストールする「パッケージ」という名前の新しいディレクトリを作成します。

   ```
   mkdir package
   ```

   .zip デプロイパッケージの場合、Lambda では、ソースコードとその依存関係がすべて .zip ファイルのルートにあると想定されていることに注意してください。ただし、依存関係をプロジェクトディレクトリに直接インストールすると、多数の新しいファイルやフォルダが追加され、IDE 内を移動することが難しくなります。依存関係をソースコードと区別するために、ここで別の `package` ディレクトリを作成します。

1. 依存関係を `package` ディレクトリにインストールします。以下の例では、pip を使用して Python パッケージインデックスから Boto3 SDK をインストールします。関数コードに自分で作成した Python パッケージを使用している場合は、それらを `package` ディレクトリに保存します。

   ```
   pip install --target ./package boto3
   ```

1. ルートにインストール済みライブラリを含む .zip ファイルを作成します。

   ```
   cd package
   zip -r ../my_deployment_package.zip .
   ```

   これにより、プロジェクトディレクトリに `my_deployment_package.zip` ファイルが生成されます。

1. .zip ファイルのルートに Lambda\$1function.py ファイルを追加します。

   ```
   cd ..
   zip my_deployment_package.zip lambda_function.py
   ```

   .zip ファイルは、次のように関数のハンドラーコードとすべての依存関係フォルダがルートにインストールされた、フラットなディレクトリ構造である必要があります。

   ```
   my_deployment_package.zip
   |- bin
   |  |-jp.py
   |- boto3
   |  |-compat.py
   |  |-data
   |  |-docs
   ...
   |- lambda_function.py
   ```

   関数のハンドラーコードを含む .py ファイルが .zip ファイルのルートにない場合、Lambda はコードを実行できません。

**デプロイパッケージ (仮想環境) を作成するには**

1. プロジェクトディレクトリに仮想環境を作成してアクティブ化します。この例では、プロジェクトディレクトリ名は `my_function` です。

   ```
   ~$ cd my_function
   ~/my_function$ python3.14 -m venv my_virtual_env
   ~/my_function$ source ./my_virtual_env/bin/activate
   ```

1. pip を使用して必要なライブラリをインストールします。次の例では、Boto3 SDK をインストールします。

   ```
   (my_virtual_env) ~/my_function$ pip install boto3
   ```

1. `pip show` を使用して、仮想環境内で pip が依存関係をインストールした場所を検索できます。

   ```
   (my_virtual_env) ~/my_function$ pip show <package_name>
   ```

   pip がライブラリをインストールするフォルダには、`site-packages` または `dist-packages` という名前を付けることができます。このフォルダは、`lib/python3.x` または `lib64/python3.x` ディレクトリ (python3.x は使用している Python のバージョンを表します) のどちらにあってもかまいません。

1. 仮想環境を無効化します。

   ```
   (my_virtual_env) ~/my_function$ deactivate
   ```

1. pip でインストールした依存関係を含むディレクトリに移動し、インストールした依存関係をルートとする .zip ファイルをプロジェクトディレクトリに作成します。この例では、pip は依存関係を `my_virtual_env/lib/python3.14/site-packages` ディレクトリにインストールしています。

   ```
   ~/my_function$ cd my_virtual_env/lib/python3.14/site-packages
   ~/my_function/my_virtual_env/lib/python3.14/site-packages$ zip -r ../../../../my_deployment_package.zip .
   ```

1. ハンドラーコードを含む .py ファイルがあるプロジェクトディレクトリのルートに移動し、そのファイルを .zip パッケージのルートに追加します。この例では、関数コードファイルに `lambda_function.py` という名前が付けられています。

   ```
   ~/my_function/my_virtual_env/lib/python3.14/site-packages$ cd ../../../../
   ~/my_function$ zip my_deployment_package.zip lambda_function.py
   ```

## 依存関係検索パスおよびランタイムを含むライブラリ
<a name="python-package-searchpath"></a>

 コードで `import` ステートメントを使用すると、Python ランタイムはモジュールまたはパッケージが見つかるまで検索パス内のディレクトリを検索します。デフォルトでは、ランタイムが最初に検索する場所は、.zip デプロイパッケージを解凍してマウントするディレクトリ (`/var/task`) です。ランタイムに含まれるライブラリのバージョンをデプロイパッケージに含める場合、そのバージョンが、ランタイムに含まれるバージョンよりも優先されます。デプロイパッケージ内の依存関係も、レイヤー内の依存関係よりも優先されます。

 レイヤーに依存関係を追加すると、Lambda はこれを `/opt/python/lib/python3.x/site-packages` (ここで `python3.x` は使用しているランタイムのバージョンを表します) または `/opt/python` に抽出します。検索パスでは、これらのディレクトリは、ランタイムに含まれるライブラリおよび pip でインストールされたライブラリを含むディレクトリ (`/var/runtime` および `/var/lang/lib/python3.x/site-packages`) よりも優先されます。このため、関数レイヤー内のライブラリは、ランタイムに含まれるバージョンよりも優先されます。

**注記**  
Python 3.11 マネージドランタイムとベースイメージでは、AWS SDK とその依存関係は `/var/lang/lib/python3.11/site-packages` ディレクトリにインストールされます。

 次のコードスニペットを追加すると、Lambda 関数の完全な検索パスを確認できます。

```
import sys
      
search_path = sys.path
print(search_path)
```

**注記**  
デプロイパッケージまたはレイヤーの依存関係はランタイムに含まれるライブラリよりも優先されるため、SDK を含めずに urllib3 などの SDK 依存関係をパッケージに含めると、バージョンの不整合の問題が発生する可能性があります。独自のバージョンの Boto3 依存関係をデプロイする場合は、Boto3 もデプロイパッケージ内の依存関係としてデプロイする必要があります。ランタイムに関数の依存関係のバージョンが含まれていても、それらをすべてパッケージ化することをお勧めします。

 .zip パッケージ内の個別のフォルダに依存関係を追加することもできます。たとえば、Boto3 SDK のバージョンを .zip パッケージ内の `common` というフォルダに追加できます。.zip パッケージを解凍してマウントすると、このフォルダは `/var/task` ディレクトリ内に配置されます。コード内の .zip デプロイパッケージ内のフォルダの依存関係を使用するには、`import from` ステートメントを使用します。たとえば、.zip パッケージ内の `common` という名前のフォルダにある Boto3 のバージョンを使用するには、次のステートメントを使用します。

```
from common import boto3
```

## \$1\$1pycache\$1\$1 フォルダを使用する
<a name="python-package-pycache"></a>

 関数のデプロイパッケージには `__pycache__` フォルダを含めないことをお勧めします。アーキテクチャやオペレーティングシステムが異なるビルドマシンでコンパイルされた Python バイトコードは、Lambda 実行環境と互換性がない場合があります。

## ネイティブライブラリとともに .zip デプロイパッケージを作成する
<a name="python-package-native-libraries"></a>

 関数で、純粋な Python パッケージとモジュールのみを使用する場合は、`pip install` コマンドを使用して任意のローカルビルドマシンに依存関係をインストールし、.zip ファイルを作成できます。NumPy や Pandas を含む一般的な Python ライブラリの多くは、純粋な Python ではなく、C または C\$1\$1 で記述されたコードを含んでいます。C/C\$1\$1 コードを含むライブラリをデプロイパッケージに追加するときは、パッケージを正しく構築し、Lambda 実行環境と互換性があることを確認する必要があります。

 Python Package インデックス ([PyPI](https://pypi.org/)) で入手できるほとんどのパッケージは、「ホイール」(.whl ファイル) として利用できます。.whl ファイルは、特定のオペレーティングシステムと命令セットアーキテクチャ用にプリコンパイルされたバイナリ、およびビルド済みディストリビューションを含む ZIP ファイルの一種です。デプロイパッケージに Lambda との互換性をもたせるには、Linux オペレーティングシステム用のホイールと関数の命令セットアーキテクチャをインストールします。

 一部のパッケージには、ソースディストリビューションとしてしか利用できないものもあります。これらのパッケージでは、C/C\$1\$1 コンポーネントを自分でコンパイルして構築する必要があります。

 必要なパッケージで利用できるディストリビューションを確認するには、以下を実行します。

1. [Python Package インデックスのメインページ](https://pypi.org/)でパッケージの名前を検索します。

1. 使用するパッケージのバージョンを選択します。

1. **[ファイルをダウンロード]** を選択します。

### ビルド済みディストリビューション (ホイール) を使用する
<a name="python-package-wheels"></a>

 Lambda と互換性のあるホイールをダウンロードするには、pip `--platform` オプションを使用します。

 Lambda 関数が **x86\$164** 命令セットアーキテクチャを使用している場合は、次の `pip install` コマンドを実行して、互換性のあるホイールを `package` ディレクトリにインストールします。`--python 3.x` を、使用している Python ランタイムのバージョンに置き換えます。

```
pip install \
--platform manylinux2014_x86_64 \
--target=package \
--implementation cp \
--python-version 3.x \
--only-binary=:all: --upgrade \
<package_name>
```

 関数が **arm64** 命令セットアーキテクチャを使用している場合は、次のコマンドを実行します。`--python 3.x` を、使用している Python ランタイムのバージョンに置き換えます。

```
pip install \
--platform manylinux2014_aarch64 \
--target=package \
--implementation cp \
--python-version 3.x \
--only-binary=:all: --upgrade \
<package_name>
```

### ソースディストリビューションを使用する
<a name="python-package-source-dist"></a>

 パッケージをソースディストリビューションとしてしか入手できない場合は、C/C\$1\$1 ライブラリを自分で構築する必要があります。パッケージに Lambda 実行環境との互換性を持たせるには、同じ Amazon Linux オペレーティングシステムを使用する環境内で構築する必要があります。これは、Amazon Elastic Compute Cloud (Amazon EC2) の Linux インスタンス内でパッケージを構築することで実現できます。

 Amazon EC2 Linux インスタンスを起動して接続する方法の詳細については、「*Amazon EC2 ユーザーガイド*」の「[Amazon EC2 の開始方法](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html)」を参照してください。

## .zip ファイルを使用した Python Lambda 関数の作成と更新
<a name="python-package-create-update"></a>

 .zip デプロイパッケージを作成したら、このパッケージを使用して新しい Lambda 関数を作成するか、既存の関数を更新できます。.zip パッケージをデプロイするには、Lambda コンソール、AWS Command Line Interface、Lambda API を使用します。AWS Serverless Application Model (AWS SAM) および CloudFormation を使用して、Lambda 関数を作成および更新することもできます。

Lambda の .zip デプロイパッケージの最大サイズは  250 MB (解凍) です。この制限は、Lambda レイヤーを含む、更新するすべてのファイルの合計サイズに適用されることに注意してください。

Lambda ランタイムには、デプロイパッケージ内のファイルを読み取るアクセス許可が必要です。Linux のアクセス権限の 8 進表記では、Lambda には非実行ファイル用に 644 のアクセス権限 (rw-r--r--) が必要であり、ディレクトリと実行可能ファイル用に 755 のアクセス権限 (rwxr-xr-x) が必要です。

Linux と MacOS で、デプロイパッケージ内のファイルやディレクトリのファイルアクセス権限を変更するには、`chmod` コマンドを使用します。例えば、実行可能でないファイルに正しいアクセス許可を付与するには、次のコマンドを実行します。

```
chmod 644 <filepath>
```

Windows でファイルアクセス許可を変更するには、「Microsoft Windows ドキュメント」の「[Set, View, Change, or Remove Permissions on an Object](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc731667(v=ws.10))」を参照してください。

**注記**  
デプロイパッケージのディレクトリにアクセスするために必要なアクセス許可を Lambda に付与しない場合、Lambda はそれらのディレクトリのアクセス許可を 755 (rwxr-xr-x) に設定します。

### コンソールを使用して .zip ファイルの関数を作成、更新する
<a name="python-package-create-console"></a>

 新しい関数を作成するには、まずコンソールで関数を作成し、次に .zip アーカイブをアップロードする必要があります。既存の関数を更新するには、その関数のページを開き、同じ手順に従って更新した .zip ファイルを追加します。

 .zip ファイルが 50 MB 未満の場合は、ローカルマシンから直接ファイルをアップロードして関数を作成または更新できます。50 MB を超える .zip ファイルの場合は、まず  Amazon S3 バケットにパッケージをアップロードする必要があります。AWS マネジメントコンソール を使用して Amazon S3 バケットにファイルをアップロードする手順については、「[Amazon S3 の開始方法](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html)」を参照してください。AWS CLI を使用してファイルをアップロードするには、「*AWS CLI ユーザーガイド*」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

**注記**  
既存の関数の[デプロイパッケージタイプ](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-PackageType) (.zip またはコンテナイメージ) を変更することはできません。例えば、既存のコンテナイメージ関数を、.zip ファイルアーカイブを使用するように変換することはできません。この場合は、新しい関数を作成する必要があります。

**新しい関数を作成するには (コンソール)**

1. Lambda コンソールの [[関数]](https://console.aws.amazon.com/lambda/home#/functions) ページを開き、**[関数の作成]** を選択します。

1. **[一から作成]** を選択します。

1. **[基本的な情報]** で、以下を行います。

   1. **[関数名]** に、関数名を入力します。

   1. **[ランタイム]** で、使用するランタイムを選択します。

   1. (オプション) **[アーキテクチャ]**で、関数の命令セットアーキテクチャを選択します。デフォルトのアーキテクチャは x86\$164 です。関数用の .zip デプロイパッケージと選択した命令セットのアーキテクチャに互換性があることを確認してください。

1. (オプション) **[アクセス権限]** で、**[デフォルトの実行ロールの変更]** を展開します。新しい **[実行ロール]** を作成することも、既存のロールを使用することもできます。

1. **[関数の作成]**を選択します。Lambda は、選択したランタイムを使用して基本的な「Hello world」関数を作成します。

**ローカルマシンから  zip アーカイブをアップロードするには (コンソール)**

1. Lambda コンソールの [[関数ページ]](https://console.aws.amazon.com/lambda/home#/functions) で、.zip ファイルをアップロードする関数を選択します。

1. **[コード]** タブを選択します。

1. **[コードソース]** ペインで、**[アップロード元]** をクリックします。

1. **[.zip ファイル]** をクリックします。

1. .zip ファイルをアップロードするには、次の操作を行います。

   1. **[アップロード]** をクリックし、ファイルセレクターで .zip ファイルを選択します。

   1. **[開く]** をクリックします。

   1. **[保存]** をクリックします。

**Amazon S3 バケットから .zip アーカイブをアップロードするには (コンソール)**

1. Lambda コンソールの [[関数ページ]](https://console.aws.amazon.com/lambda/home#/functions) で、新しい .zip ファイルをアップロードする関数を選択します。

1. **[コード]** タブを選択します。

1. **[コードソース]** ペインで、**[アップロード元]** をクリックします。

1. **[Amazon S3 ロケーション]** を選択します。

1. .zip ファイルの Amazon S3 リンク URL を貼り付けて、**[保存]** を選択します。

### コンソールコードエディタを使用して .zip ファイル関数を更新する
<a name="python-package-console-edit"></a>

 .zip デプロイパッケージを使用する一部の関数では、Lambda コンソールの組み込みコードエディタを使用して、関数コードを直接更新できます。この機能を使用するには、関数が次の基準を満たしている必要があります。
+ 関数が、インタープリター言語ランタイムのいずれか (Python、Node.js、Ruby) を使用する必要があります。
+ 関数のデプロイパッケージが 50 MB (解凍時)未満である必要があります。

コンテナイメージデプロイパッケージを含む関数の関数コードは、コンソールで直接編集することはできません。

**コンソールのコードエディタを使用して関数コードを更新するには**

1. Lambda コンソールの「[関数ページ](https://console.aws.amazon.com/lambda/home#/functions)」を開き、関数を選択します。

1. **[コード]** タブを選択します。

1. **[コードソース]** ペインでソースコードファイルを選択し、統合コードエディタで編集します。

1. **[DEPLOY]** セクションで、**[デプロイ]** を選択して関数のコードを更新します。  
![\[\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

### AWS CLI を使用して .zip ファイルで関数を作成、更新する
<a name="python-package-create-cli"></a>

 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) を使用して新しい関数を作成したり、.zip ファイルを使用して既存の関数を更新したりできます。[create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) コマンドと [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) を使用して、.zip パッケージをデプロイします。.zip ファイルが 50 MB 未満の場合は、ローカルビルドマシン上のファイルの場所から .zip パッケージをアップロードできます。サイズの大きいファイルの場合は、Amazon S3 バケットから .zip パッケージをアップロードする必要があります。AWS CLI を使用して Amazon S3 バケットにファイルをアップロードする方法については、「*AWS CLI ユーザーガイド*」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

**注記**  
AWS CLI を使用して Amazon S3 バケットから .zip ファイルをアップロードする場合、このバケットは関数と同じ AWS リージョン に配置する必要があります。

 AWS CLI を含む .zip ファイルを使用して新しい関数を作成するには、以下を指定する必要があります。
+ 関数の名前 (`--function-name`)
+ 関数のランタイム (`--runtime`)
+ 関数の[実行ロール](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) (`--role`) の Amazon リソースネーム (ARN)
+ 関数コード内のハンドラーメソッド (`--handler`) の名前

 .zip ファイルの場所も指定する必要があります。.zip ファイルがローカルビルドマシン上のフォルダにある場合は、次のコマンド例に示すように、`--zip-file` オプションを使用してファイルパスを指定します。

```
aws lambda create-function --function-name myFunction \
--runtime python3.14 --handler lambda_function.lambda_handler \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--zip-file fileb://myFunction.zip
```

 Amazon S3 バケット内の .zip ファイルの場所を指定するには、以下のコマンド例にある `--code` オプションを使用します。`S3ObjectVersion` パラメータは、バージョン管理下のオブジェクトにのみ使用する必要があります。

```
aws lambda create-function --function-name myFunction \
--runtime python3.14 --handler lambda_function.lambda_handler \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--code S3Bucket=amzn-s3-demo-bucket,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion
```

 CLI を使用して既存の関数を更新するには、`--function-name` パラメータを使用して関数の名前を指定します。関数コードの更新に使用する .zip ファイルの場所も指定する必要があります。.zip ファイルがローカルビルドマシン上のフォルダにある場合は、次のコマンド例に示すように、`--zip-file` オプションを使用してファイルパスを指定します。

```
aws lambda update-function-code --function-name myFunction \
--zip-file fileb://myFunction.zip
```

 Amazon S3 バケット内の .zip ファイルの場所を指定するには、以下のコマンド例にある `--s3-bucket` および `--s3-key` オプションを使用します。`--s3-object-version` パラメータは、バージョン管理下のオブジェクトにのみ使用する必要があります。

```
aws lambda update-function-code --function-name myFunction \
--s3-bucket amzn-s3-demo-bucket --s3-key myFileName.zip --s3-object-version myObject Version
```

### Lambda API を使用して .zip ファイルで関数を作成、更新する
<a name="python-package-create-api"></a>

 .zip ファイルアーカイブを使用して関数を作成および更新するには、以下の API オペレーションを使用します。
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)

### AWS SAM を使用して .zip ファイルで関数を作成、更新する
<a name="python-package-create-sam"></a>

 AWS Serverless Application Model (AWS SAM) は、AWS のサーバーレスアプリケーションの構築と実行のプロセスを合理化するのに役立つツールキットです。YAML または JSON テンプレートでアプリケーションのリソースを定義し、AWS SAM コマンドラインインターフェイス (AWS SAM CLI) を使用して、アプリケーションを構築、パッケージ化、デプロイします。AWS SAM テンプレートから Lambda 関数を構築すると、AWS SAM は関数コードと指定した任意の依存関係を含む .zip デプロイパッケージまたはコンテナイメージを自動的に作成します。AWS SAM を使用して Lambda 関数を構築およびデプロイする方法の詳細については、「*AWS Serverless Application Model デベロッパーガイド*」の「[Getting started with AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html)」を参照してください。

AWS SAM を使用して、既存の .zip ファイルアーカイブを使用する Lambda 関数を作成できます。AWS SAM を使用して Lambda 関数を作成するには、.zip  ファイルを Amazon S3 バケットまたはビルドマシンのローカルフォルダに保存します。AWS CLI を使用して Amazon S3 バケットにファイルをアップロードする方法については、「*AWS CLI ユーザーガイド*」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

 AWS SAM テンプレートでは、Lambda 関数は `AWS::Serverless::Function` のリソースにより指定されます。このリソースで次のプロパティを設定し、.zip ファイルアーカイブを使用して関数を作成します。
+ `PackageType` - `Zip` に設定
+ `CodeUri` - 関数コードの Amazon S3 URI、ローカルフォルダへのパス、または [FunctionCode](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-functioncode.html) オブジェクトに設定
+ `Runtime` - 選択したランタイムに設定

 AWS SAM では、.zip ファイルが 50 MB を超える場合、この .zip ファイルを最初に Amazon S3 バケットにアップロードする必要はありません。AWS SAM では、ローカルビルドマシン上の場所から、最大許容サイズ 250 MB (解凍) の .zip パッケージをアップロードできます。

 AWS SAM で .zip ファイルを使用して関数をデプロイする方法の詳細については、「*AWS SAM デベロッパーガイド*」の「[AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)」を参照してください。

### CloudFormation を使用して .zip ファイルで関数を作成、更新する
<a name="python-package-create-cfn"></a>

 CloudFormation を使用して、.zip ファイルアーカイブを使用する Lambda 関数を作成できます。.zip ファイルから Lambda 関数を作成するには、最初にファイルを Amazon S3 バケットにアップロードする必要があります。AWS CLI を使用して Amazon S3 バケットにファイルをアップロードする方法については、「*AWS CLI ユーザーガイド*」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

Node.js と Python のランタイムでは、CloudFormation テンプレートにインラインソースコードを提供することもできます。CloudFormation は、関数を構築するときにコードを含む .zip ファイルを作成します。

**既存の .zip ファイルを使用する**

CloudFormation テンプレートでは、Lambda 関数は `AWS::Lambda::Function` のリソースにより指定されます。このリソースで次のプロパティを設定し、.zip ファイルアーカイブを使用して関数を作成します。
+ `PackageType` - `Zip` に設定
+ `Code` - `S3Bucket` および `S3Key` フィールドに Amazon S3 バケット名と .zip ファイル名を入力
+ `Runtime` - 選択したランタイムに設定

**インラインコードから .zip ファイルを作成する**

Python で記述された単純な関数や Node.js インラインを CloudFormation テンプレートで宣言できます。コードは YAML または JSON に埋め込まれているため、デプロイパッケージに外部依存関係を追加することはできません。つまり、関数はランタイムに含まれている AWS SDK のバージョンを使用する必要があります。特定の文字をエスケープする必要があるなどのテンプレートの要件も、IDE の構文チェックやコード補完機能の使用を難しくします。つまり、テンプレートに追加のテストが必要な場合があります。このような制限があるため、関数をインラインで宣言することは、頻繁に変更しない非常に単純なコードに最適です。

Node.js および Python ランタイムのインラインコードから .zip ファイルを作成するには、テンプレートの `AWS::Lambda::Function` リソースに次のプロパティを設定します。
+ `PackageType` が `Zip` に設定されている場合
+ `Code` - `ZipFile` フィールドに関数コードを入力します。
+ `Runtime` - 選択したランタイムに設定

 CloudFormation が生成する .zip ファイルは、4 MB を超えることはできません。CloudFormation で .zip ファイルを使用して関数をデプロイする方法の詳細については、「*CloudFormation ユーザーガイド*」の「[AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)」を参照してください。

# コンテナイメージで Python Lambda 関数をデプロイする
<a name="python-image"></a>

Python Lambda 関数のコンテナイメージを構築するには 3 つの方法があります。
+ [Python の AWS ベースイメージを使用する](#python-image-instructions)

  [AWS ベースイメージ](images-create.md#runtimes-images-lp)には、言語ランタイム、Lambda と関数コード間のやり取りを管理するランタイムインターフェースクライアント、ローカルテスト用のランタイムインターフェースエミュレーターがあらかじめロードされています。
+ [AWS の OS 専用ベースイメージを使用する](images-create.md#runtimes-images-provided)

  [AWS OS 専用ベースイメージ](https://gallery.ecr.aws/lambda/provided)には、Amazon Linux ディストリビューションおよび[ランタイムインターフェイスエミュレータ](https://github.com/aws/aws-lambda-runtime-interface-emulator/)が含まれています。これらのイメージは、[Go](go-image.md#go-image-provided) や [Rust](lambda-rust.md) などのコンパイル済み言語や、Lambda がベースイメージを提供していない言語または言語バージョン (Node.js 19 など) のコンテナイメージの作成によく使用されます。OS 専用のベースイメージを使用して[カスタムランタイム](runtimes-custom.md)を実装することもできます。イメージに Lambda との互換性を持たせるには、[Python のランタイムインターフェイスクライアント](#python-image-clients)をイメージに含める必要があります。
+ [非 AWS ベースイメージを使用する](#python-image-clients)

  Alpine Linux や Debian など、別のコンテナレジストリの代替ベースイメージを使用することができます。組織が作成したカスタムイメージを使用することもできます。イメージに Lambda との互換性を持たせるには、[Python のランタイムインターフェイスクライアント](#python-image-clients)をイメージに含める必要があります。

**ヒント**  
Lambda コンテナ関数がアクティブになるまでの時間を短縮するには、「Docker ドキュメント」の「[マルチステージビルドを使用する](https://docs.docker.com/build/building/multi-stage/)」を参照してください。効率的なコンテナイメージを構築するには、「[Dockerfiles を記述するためのベストプラクティス](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)」に従ってください。

このページでは、Lambda のコンテナイメージを構築、テスト、デプロイする方法について説明します。

**Topics**
+ [Python の AWS ベースイメージ](#python-image-base)
+ [Python の AWS ベースイメージを使用する](#python-image-instructions)
+ [ランタイムインターフェイスクライアントで代替ベースイメージを使用する](#python-image-clients)

## Python の AWS ベースイメージ
<a name="python-image-base"></a>

AWS は、Python 用の次のベースイメージを提供します。


| タグ | ランタイム | オペレーティングシステム | Dockerfile | 非推奨 | 
| --- | --- | --- | --- | --- | 
| 3.14 | Python 3.14 | Amazon Linux 2023 | [GitHub の Python 3.14 用 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/python3.14/Dockerfile.python3.14) |   2029 年 6 月 30 日   | 
| 3.13 | Python 3.13 | Amazon Linux 2023 | [GitHub の Python 3.13 用 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/python3.13/Dockerfile.python3.13) |   2029 年 6 月 30 日   | 
| 3.12 | Python 3.12 | Amazon Linux 2023 | [GitHub の Python 3.12 用 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/python3.12/Dockerfile.python3.12) |   2028 年 10 月 31 日   | 
| 3.11 | Python 3.11 | Amazon Linux 2 | [GitHub の Python 3.11 用 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/python3.11/Dockerfile.python3.11) |   2027 年 6 月 30 日   | 
| 3.10 | Python 3.10 | Amazon Linux 2 | [GitHub の Python 3.10 用 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/python3.10/Dockerfile.python3.10) |   2026 年 10 月 31 日   | 

Amazon ECR リポジトリ: [gallery.ecr.aws/lambda/python](https://gallery.ecr.aws/lambda/python)

Python 3.12 以降のベースイメージは、[Amazon Linux 2023 の最小コンテナイメージ](https://docs.aws.amazon.com/linux/al2023/ug/minimal-container.html)に基づいています。Python 3.8～3.11 のベースイメージは、Amazon Linux 2 のイメージに基づいています。AL2023 ベースのイメージには、デプロイのフットプリントが小さいことや、`glibc` などのライブラリのバージョンが更新されていることなど、Amazon Linux 2 に比べていくつかの利点があります。

AL2023 ベースのイメージでは、Amazon Linux 2 のデフォルトのパッケージマネージャである `yum` の代わりに `microdnf` (`dnf` としてシンボリックリンク) がパッケージマネージャとして使用されています。`microdnf` は `dnf` のスタンドアロン実装です。AL2023 ベースのイメージに含まれるパッケージのリストについては、「[Comparing packages installed on Amazon Linux 2023 Container Images](https://docs.aws.amazon.com/linux/al2023/ug/al2023-container-image-types.html)」の「**Minimal Container**」列を参照してください。AL2023 と Amazon Linux 2 の違いの詳細については、AWS コンピューティングブログの「[Introducing the Amazon Linux 2023 runtime for AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-amazon-linux-2023-runtime-for-aws-lambda/)」を参照してください。

**注記**  
AWS Serverless Application Model (AWS SAM) を含む AL2023 ベースのイメージをローカルで実行するには、Docker バージョン 20.10.10 以降を使用する必要があります。

### ベースイメージ内の依存関係の検索パス
<a name="python-image-searchpath"></a>

コードで `import` ステートメントを使用すると、Python ランタイムはモジュールまたはパッケージが見つかるまで検索パス内のディレクトリを検索します。デフォルトでは、ランタイムは `{LAMBDA_TASK_ROOT}` ディレクトリを先に検索します。ランタイムに含まれるライブラリのバージョンをイメージに含める場合、そのバージョンが、ランタイムに含まれるバージョンよりも優先されます。

検索パスの他のステップは、使用している Python 用 Lambda ベースイメージのバージョンによって次のように異なります。
+ **Python 3.11 以降**: ランタイムに含まれるライブラリと pip でインストールされるライブラリは `/var/lang/lib/python3.11/site-packages` ディレクトリにインストールされます。このディレクトリは、検索パス内で `/var/runtime` よりも優先されます。pip を使用して新しいバージョンをインストールすることで、SDK をオーバーライドできます。pip を使用して、ランタイムに含まれる SDK とその依存関係が、インストールする任意のパッケージと互換性があることを確認できます。
+ **Python 3.8-3.10**: ランタイムに含まれるライブラリは `/var/runtime` ディレクトリにインストールされます。pip でインストールされるライブラリは `/var/lang/lib/python3.x/site-packages` ディレクトリにインストールされます。`/var/runtime` ディレクトリは検索パス内で `/var/lang/lib/python3.x/site-packages` より優先されます。

次のコードスニペットを追加すると、Lambda 関数の完全な検索パスを確認できます。

```
import sys
      
search_path = sys.path
print(search_path)
```

## Python の AWS ベースイメージを使用する
<a name="python-image-instructions"></a>

### 前提条件
<a name="python-image-prerequisites"></a>

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最小バージョン 25.0.0)
+ Docker [buildx プラグイン](https://github.com/docker/buildx/blob/master/README.md)。
+ Python

### ベースイメージからイメージを作成する
<a name="python-image-create"></a>

**Python の AWS ベースイメージからコンテナイメージを作成するには**

1. プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。

   ```
   mkdir example
   cd example
   ```

1. `lambda_function.py` という名前の新しいファイルを作成します。テスト用に次のサンプル関数コードをファイルに追加することも、独自のコードを使用することもできます。  
**Example Python 関数**  

   ```
   import sys
   def handler(event, context):
       return 'Hello from AWS Lambda using Python' + sys.version + '!'
   ```

1. `requirements.txt` という名前の新しいファイルを作成します。前のステップのサンプル関数コードを使用している場合、依存関係がないためファイルを空のままにしておくことができます。それ以外の場合は、必要なライブラリをそれぞれリストしてください。たとえば、関数で AWS SDK for Python (Boto3) を使用している場合、`requirements.txt` は次のようになります。  
**Example requirements.txt**  

   ```
   boto3
   ```

1. 次の設定で新しい Dockerfile を作成します。
   + `FROM` プロパティを「[ベースイメージの URI](https://gallery.ecr.aws/lambda/python/)」に設定します。
   + COPY コマンドを使用し、関数コードおよびランタイムの依存関係を `{LAMBDA_TASK_ROOT}` ([Lambda 定義の環境変数](configuration-envvars.md#configuration-envvars-runtime)) にコピーします。
   + `CMD` 引数を Lambda 関数ハンドラーに設定します。

   この例の Dockerfile には [USER 命令](https://docs.docker.com/reference/dockerfile/#user)が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、`USER` 命令を指定しなかったときに `root` ユーザーのデフォルトとなる動作のことです。  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/lambda/python:3.12
   
   # Copy requirements.txt
   COPY requirements.txt ${LAMBDA_TASK_ROOT}
   
   # Install the specified packages
   RUN pip install -r requirements.txt
   
   # Copy function code
   COPY lambda_function.py ${LAMBDA_TASK_ROOT}
   
   # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
   CMD [ "lambda_function.handler" ]
   ```

1. Docker イメージを「[Docker の構築](https://docs.docker.com/engine/reference/commandline/build/)」コマンドで構築します。次の例では、イメージを `docker-image` と名付けて `test` [タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)を付けます。Lambda互換のイメージを作成するには、 `--provenance=false` オプションを使用する必要があります。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注記**  
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する `--platform linux/amd64` オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに `--platform linux/arm64` オプションを使用するようにコマンドを変更してください。

### (オプション) イメージをローカルでテストする
<a name="python-image-test"></a>

1. **docker run** コマンドを使用して、Docker イメージを起動します。この例では、`docker-image` はイメージ名、`test` はタグです。

   ```
   docker run --platform linux/amd64 -p 9000:8080 docker-image:test
   ```

   このコマンドはイメージをコンテナとして実行し、`localhost:9000/2015-03-31/functions/function/invocations` でローカルエンドポイントを作成します。
**注記**  
ARM64 命令セットアーキテクチャ用に Docker イメージをビルドした場合は、`--platform linux/amd64` の代わりに `--platform linux/arm64` オプションを使用してください。

1. 新しいターミナルウィンドウから、イベントをローカルエンドポイントにポストします。

------
#### [ Linux/macOS ]

   Linux および macOS では、次の `curl` コマンドを実行します。

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   このコマンドは、空のイベントで関数を呼び出し、応答を返します。サンプル関数コードではなく独自の関数コードを使用している場合は、JSON ペイロードを使用して関数を呼び出すことをお勧めします。例:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   PowerShell で次の `Invoke-WebRequest` コマンドを実行します。

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   このコマンドは、空のイベントで関数を呼び出し、応答を返します。サンプル関数コードではなく独自の関数コードを使用している場合は、JSON ペイロードを使用して関数を呼び出すことをお勧めします。例:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. コンテナ ID を取得します。

   ```
   docker ps
   ```

1. 「[docker kill](https://docs.docker.com/engine/reference/commandline/kill/)」コマンドを使用してコンテナを停止します。このコマンドでは、`3766c4ab331c` を前のステップのコンテナ ID で置き換えます。

   ```
   docker kill 3766c4ab331c
   ```

### イメージのデプロイ
<a name="python-image-deploy"></a>

**Amazon ECR にイメージをアップロードして Lambda 関数を作成するには**

1. 「[get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html)」コマンドを実行して Amazon ECR レジストリに Docker CLI を認証します。
   + `--region` 値を Amazon ECR リポジトリを作成する AWS リージョン に設定します。
   + `111122223333` を AWS アカウント ID に置き換えます。

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 「[create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html)」コマンドを使用して Amazon ECR にリポジトリを作成します。

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**注記**  
Amazon ECR リポジトリは Lambda 関数と同じ AWS リージョン に配置されている必要があります。

   成功すると、次のようなレスポンスが表示されます。

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 前のステップの出力から `repositoryUri` をコピーします。

1. 「[docker tag](https://docs.docker.com/engine/reference/commandline/tag/)」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで:
   + `docker-image:test` は、Docker イメージの名前と[タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)です。これは、`docker build` コマンドに指定したイメージの名前とタグです。
   + `<ECRrepositoryUri>` を、コピーした `repositoryUri` に置き換えます。URI の末尾には必ず `:latest` を含めてください。

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   例:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 「[docker push](https://docs.docker.com/engine/reference/commandline/push/)」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず `:latest` を含めてください。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. まだ作成済みでない場合、関数に「[実行ロールの作成](lambda-intro-execution-role.md#permissions-executionrole-api)」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。

1. Lambda 関数を作成します。`ImageUri` には、先ほど使用したリポジトリ URI を指定します。URI の末尾には必ず `:latest` を含めてください。

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注記**  
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「[Amazon ECR クロスアカウント許可](images-create.md#configuration-images-xaccount-permissions)」を参照してください。

1. 関数を呼び出します。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   次のような結果が表示されます。

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 関数の出力を確認するには、`response.json` ファイルをチェックします。

関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用してイメージを Lambda 関数にデプロイする必要があります。

Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。

新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用する必要があります。次の例では、`--publish` オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

## ランタイムインターフェイスクライアントで代替ベースイメージを使用する
<a name="python-image-clients"></a>

[OS 専用ベースイメージ](images-create.md#runtimes-images-provided)または代替のベースイメージを使用する場合、イメージにランタイムインターフェイスクライアントを含める必要があります。ランタイムインターフェイスクライアントは、Lambda と関数コード間の相互作用を管理する [ランタイム API](runtimes-api.md) を拡張します。

pip パッケージマネージャーを使用して、[Python 用のランタイムインターフェイスクライアント](https://pypi.org/project/awslambdaric)をインストールします。

```
pip install awslambdaric
```

[Python ランタイムインターフェイスクライアント ](https://github.com/aws/aws-lambda-python-runtime-interface-client/)を GitHub からダウンロードすることもできます。

次の例は、非 AWS ベースイメージを使用して Python 用のコンテナイメージを構築する方法を示しています。サンプルの Dockerfile は公式の Python ベースイメージを使用しています。Dockerfile には、Python 用のランタイムインターフェイスクライアントが含まれます。

### 前提条件
<a name="python-alt-prerequisites"></a>

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最小バージョン 25.0.0)
+ Docker [buildx プラグイン](https://github.com/docker/buildx/blob/master/README.md)。
+ Python

### 代替ベースイメージからイメージを作成する
<a name="python-alt-create"></a>

**非 AWS ベースイメージからコンテナイメージを作成するには**

1. プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。

   ```
   mkdir example
   cd example
   ```

1. `lambda_function.py` という名前の新しいファイルを作成します。テスト用に次のサンプル関数コードをファイルに追加することも、独自のコードを使用することもできます。  
**Example Python 関数**  

   ```
   import sys
   def handler(event, context):
       return 'Hello from AWS Lambda using Python' + sys.version + '!'
   ```

1. `requirements.txt` という名前の新しいファイルを作成します。前のステップのサンプル関数コードを使用している場合、依存関係がないためファイルを空のままにしておくことができます。それ以外の場合は、必要なライブラリをそれぞれリストしてください。たとえば、関数で AWS SDK for Python (Boto3) を使用している場合、`requirements.txt` は次のようになります。  
**Example requirements.txt**  

   ```
   boto3
   ```

1. 新しい Dockerfile を作成します。次の Dockerfile は、[AWS ベースイメージ](images-create.md#runtimes-images-lp)の代わりに公式の Python ベースイメージを使用しています。Dockerfile には、イメージに Lambda との互換性を持たせる[ランタイムインターフェイスクライアント](https://pypi.org/project/awslambdaric)が含まれています。次の Dockerfile の例では、「[マルチステージビルド](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)」が使用されます。
   + `FROM` プロパティにベースイメージを設定します。
   + `ENTRYPOINT` を、Docker コンテナの起動時に実行させるモジュールに設定します。この場合、モジュールはランタイムインターフェイスクライアントです。
   + `CMD` を Lambda 関数ハンドラーに設定します。

   この例の Dockerfile には [USER 命令](https://docs.docker.com/reference/dockerfile/#user)が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、`USER` 命令を指定しなかったときに `root` ユーザーのデフォルトとなる動作のことです。  
**Example Dockerfile**  

   ```
   # Define custom function directory
   ARG FUNCTION_DIR="/function"
   
   FROM python:3.12 AS build-image
   
   # Include global arg in this stage of the build
   ARG FUNCTION_DIR
   
   # Copy function code
   RUN mkdir -p ${FUNCTION_DIR}
   COPY . ${FUNCTION_DIR}
   
   # Install the function's dependencies
   RUN pip install \
       --target ${FUNCTION_DIR} \
           awslambdaric
   
   # Use a slim version of the base Python image to reduce the final image size
   FROM python:3.12-slim
   
   # Include global arg in this stage of the build
   ARG FUNCTION_DIR
   # Set working directory to function root directory
   WORKDIR ${FUNCTION_DIR}
   
   # Copy in the built dependencies
   COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}
   
   # Set runtime interface client as default command for the container runtime
   ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
   # Pass the name of the function handler as an argument to the runtime
   CMD [ "lambda_function.handler" ]
   ```

1. Docker イメージを「[Docker の構築](https://docs.docker.com/engine/reference/commandline/build/)」コマンドで構築します。次の例では、イメージを `docker-image` と名付けて `test` [タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)を付けます。Lambda互換のイメージを作成するには、 `--provenance=false` オプションを使用する必要があります。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注記**  
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する `--platform linux/amd64` オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに `--platform linux/arm64` オプションを使用するようにコマンドを変更してください。

### (オプション) イメージをローカルでテストする
<a name="python-alt-test"></a>

[ランタイムインターフェイスエミュレーター](https://github.com/aws/aws-lambda-runtime-interface-emulator/)を使用して、イメージをローカルでテストします。[エミュレーターはイメージに組み込むことも](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image)、次の手順を使用してローカルマシンにインストールすることもできます。

**ローカルマシンにランタイムインターフェイスエミュレーターをインストールして実行するには**

1. プロジェクトディレクトリから次のコマンドを実行して、GitHub からランタイムインターフェイスエミュレーター (x86-64 アーキテクチャ) をダウンロードし、ローカルマシンにインストールします。

------
#### [ Linux/macOS ]

   ```
   mkdir -p ~/.aws-lambda-rie && \
       curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
       chmod +x ~/.aws-lambda-rie/aws-lambda-rie
   ```

   arm64 エミュレータをインストールするには、前のコマンドの GitHub リポジトリ URL を次のように置き換えます。

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------
#### [ PowerShell ]

   ```
   $dirPath = "$HOME\.aws-lambda-rie"
   if (-not (Test-Path $dirPath)) {
       New-Item -Path $dirPath -ItemType Directory
   }
         
   $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie"
   $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie"
   Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath
   ```

   arm64 エミュレーターをインストールするには、`$downloadLink` を次のように置き換えます。

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------

1. **docker run** コマンドを使用して、Docker イメージを起動します。次の点に注意してください。
   + `docker-image` はイメージ名、`test` はタグです。
   + `/usr/local/bin/python -m awslambdaric lambda_function.handler` は `ENTRYPOINT` で、その後に Dockerfile の `CMD` が続きます。

------
#### [ Linux/macOS ]

   ```
   docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
       --entrypoint /aws-lambda/aws-lambda-rie \
       docker-image:test \
           /usr/local/bin/python -m awslambdaric lambda_function.handler
   ```

------
#### [ PowerShell ]

   ```
   docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 `
   --entrypoint /aws-lambda/aws-lambda-rie `
   docker-image:test `
       /usr/local/bin/python -m awslambdaric lambda_function.handler
   ```

------

   このコマンドはイメージをコンテナとして実行し、`localhost:9000/2015-03-31/functions/function/invocations` でローカルエンドポイントを作成します。
**注記**  
ARM64 命令セットアーキテクチャ用に Docker イメージをビルドした場合は、`--platform linux/amd64` の代わりに `--platform linux/arm64` オプションを使用してください。

1. イベントをローカルエンドポイントにポストします。

------
#### [ Linux/macOS ]

   Linux および macOS では、次の `curl` コマンドを実行します。

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   このコマンドは、空のイベントで関数を呼び出し、応答を返します。サンプル関数コードではなく独自の関数コードを使用している場合は、JSON ペイロードを使用して関数を呼び出すことをお勧めします。例:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   PowerShell で次の `Invoke-WebRequest` コマンドを実行します。

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   このコマンドは、空のイベントで関数を呼び出し、応答を返します。サンプル関数コードではなく独自の関数コードを使用している場合は、JSON ペイロードを使用して関数を呼び出すことをお勧めします。例:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. コンテナ ID を取得します。

   ```
   docker ps
   ```

1. 「[docker kill](https://docs.docker.com/engine/reference/commandline/kill/)」コマンドを使用してコンテナを停止します。このコマンドでは、`3766c4ab331c` を前のステップのコンテナ ID で置き換えます。

   ```
   docker kill 3766c4ab331c
   ```

### イメージのデプロイ
<a name="python-alt-deploy"></a>

**Amazon ECR にイメージをアップロードして Lambda 関数を作成するには**

1. 「[get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html)」コマンドを実行して Amazon ECR レジストリに Docker CLI を認証します。
   + `--region` 値を Amazon ECR リポジトリを作成する AWS リージョン に設定します。
   + `111122223333` を AWS アカウント ID に置き換えます。

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 「[create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html)」コマンドを使用して Amazon ECR にリポジトリを作成します。

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**注記**  
Amazon ECR リポジトリは Lambda 関数と同じ AWS リージョン に配置されている必要があります。

   成功すると、次のようなレスポンスが表示されます。

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 前のステップの出力から `repositoryUri` をコピーします。

1. 「[docker tag](https://docs.docker.com/engine/reference/commandline/tag/)」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで:
   + `docker-image:test` は、Docker イメージの名前と[タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)です。これは、`docker build` コマンドに指定したイメージの名前とタグです。
   + `<ECRrepositoryUri>` を、コピーした `repositoryUri` に置き換えます。URI の末尾には必ず `:latest` を含めてください。

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   例:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 「[docker push](https://docs.docker.com/engine/reference/commandline/push/)」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず `:latest` を含めてください。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. まだ作成済みでない場合、関数に「[実行ロールの作成](lambda-intro-execution-role.md#permissions-executionrole-api)」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。

1. Lambda 関数を作成します。`ImageUri` には、先ほど使用したリポジトリ URI を指定します。URI の末尾には必ず `:latest` を含めてください。

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注記**  
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「[Amazon ECR クロスアカウント許可](images-create.md#configuration-images-xaccount-permissions)」を参照してください。

1. 関数を呼び出します。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   次のような結果が表示されます。

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 関数の出力を確認するには、`response.json` ファイルをチェックします。

関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用してイメージを Lambda 関数にデプロイする必要があります。

Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。

新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用する必要があります。次の例では、`--publish` オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

Alpine ベースイメージから Python イメージを作成する方法の例については、AWS ブログの「[Lambda のコンテナイメージのサポート](https://aws.amazon.com/blogs/aws/new-for-aws-lambda-container-image-support/)」を参照してください。

# Python Lambda 関数にレイヤーを使用する
<a name="python-layers"></a>

[Lambda レイヤー](chapter-layers.md)を使用して、複数の関数間で再利用するコードおよび依存関係をパッケージ化できます。レイヤーには通常、ライブラリの依存関係、[カスタムランタイム](runtimes-custom.md)、または設定ファイルが含まれています。レイヤーの作成には、次の 3 つの一般的な手順が含まれます。

1. レイヤーコンテンツのパッケージ化。これは、関数で使用する依存関係を含む .zip ファイルアーカイブを作成することを意味します。

1. Lambda でレイヤーを作成します。

1. レイヤーを関数に追加します。

**Topics**
+ [レイヤーコンテンツのパッケージ化](#python-layers-package)
+ [Lambda でレイヤーを作成する](#publishing-layer)
+ [レイヤーを関数に追加する](#python-layer-adding)
+ [サンプルアプリ](#python-layer-sample-app)

## レイヤーコンテンツのパッケージ化
<a name="python-layers-package"></a>

レイヤーを作成するには、次の要件を満たす .zip ファイルのアーカイブにパッケージをバンドルします。
+ Lambda 関数に使用するのと同じ Python バージョンを使用してレイヤーを構築すること。例えば、Python 3.14 を使用してレイヤーを構築する場合、関数にも Python 3.14 ランタイムを使用してください。
+ .zip ファイルは、ルートレベルに `python` ディレクトリを含む必要があります。
+ レイヤーのパッケージは Linux と互換性がある必要があります。Lambda 関数は Amazon Linux 上で動作します。

`pip` がインストールされたサードパーティ Python ライブラリ (`requests` や `pandas` など) か、ユーザー独自の Python モジュールやパッケージのいずれかを含むレイヤーを作成できます。

### サードパーティーへの依存関係
<a name="python-layers-third-party-dependencies"></a>

**pip パッケージを使用してレイヤーを作成する方法**

1. 次のいずれかの方法を選択し、必要な最上位ディレクトリ (`python/`) に `pip` パッケージをインストールします。

------
#### [ pip install ]

   純粋な Python パッケージ (リクエストや boto3 など) の場合、以下に留意してください。

   ```
   pip install requests -t python/
   ```

   NumPy や Pandas などの一部の Python パッケージには、コンパイルされた C コンポーネントが含まれています。macOS または Windows でこれらのパッケージのレイヤーを構築する場合、次のコマンドを使用して Linux 互換のホイールをインストールする必要があるかもしれません。

   ```
   pip install numpy --platform manylinux2014_x86_64 --only-binary=:all: -t python/
   ```

   コンパイルされたコンポーネントを含む Python パッケージ操作の詳細については、「[ネイティブライブラリとともに .zip デプロイパッケージを作成する](python-package.md#python-package-native-libraries)」を参照してください。

------
#### [ requirements.txt ]

   `requirements.txt` ファイルを使用すると、パッケージバージョンを管理して一貫性のあるインストールを確保できます。

**Example requirements.txt**  

   ```
   requests==2.31.0
   boto3==1.37.34
   numpy==1.26.4
   ```

   `requirements.txt` ファイルに純粋な Python パッケージ (リクエストや boto3 など) のみが含まれている場合、以下に留意してください。

   ```
   pip install -r requirements.txt -t python/
   ```

   NumPy や Pandas などの一部の Python パッケージには、コンパイルされた C コンポーネントが含まれています。macOS または Windows でこれらのパッケージのレイヤーを構築する場合、次のコマンドを使用して Linux 互換のホイールをインストールする必要があるかもしれません。

   ```
   pip install -r requirements.txt --platform manylinux2014_x86_64 --only-binary=:all: -t python/
   ```

   コンパイルされたコンポーネントを含む Python パッケージ操作の詳細については、「[ネイティブライブラリとともに .zip デプロイパッケージを作成する](python-package.md#python-package-native-libraries)」を参照してください。

------

1. `python` ディレクトリの内容を圧縮します。

------
#### [ Linux/macOS ]

   ```
   zip -r layer.zip python/
   ```

------
#### [ PowerShell ]

   ```
   Compress-Archive -Path .\python -DestinationPath .\layer.zip
   ```

------

   .zip ファイルのディレクトリ構造は次のようになります。

   ```
   python/              # Required top-level directory
   └── requests/
   └── boto3/
   └── numpy/
   └── (dependencies of the other packages)
   ```
**注記**  
Python 仮想環境 (venv) を使用してパッケージをインストールする場合、ディレクトリ構造はこれとは異なります (`python/lib/python3.x/site-packages` など)。.zip ファイルにルートレベルの `python` ディレクトリが含まれる限り、Lambda はパッケージを見つけてインポートすることができます。

### カスタム Python モジュール
<a name="custom-python-modules"></a>

**ユーザー独自のコードを使用してレイヤーを作成する方法**

1. レイヤーに必要な最上位ディレクトリを作成します。

   ```
   mkdir python
   ```

1. `python` ディレクトリに Python モジュールを作成します。次のモジュール例は、必要な情報が含まれていることを確認して注文をバリデーションします。  
**Example カスタムモジュール: validator.py**  

   ```
   import json
   
   def validate_order(order_data):
       """Validates an order and returns formatted data."""
       required_fields = ['product_id', 'quantity']
       
       # Check required fields
       missing_fields = [field for field in required_fields if field not in order_data]
       if missing_fields:
           raise ValueError(f"Missing required fields: {', '.join(missing_fields)}")
       
       # Validate quantity
       quantity = order_data['quantity']
       if not isinstance(quantity, int) or quantity < 1:
           raise ValueError("Quantity must be a positive integer")
       
       # Format and return the validated data
       return {
           'product_id': str(order_data['product_id']),
           'quantity': quantity,
           'shipping_priority': order_data.get('priority', 'standard')
       }
   
   def format_response(status_code, body):
       """Formats the API response."""
       return {
           'statusCode': status_code,
           'body': json.dumps(body)
       }
   ```

1. `python` ディレクトリの内容を圧縮します。

------
#### [ Linux/macOS ]

   ```
   zip -r layer.zip python/
   ```

------
#### [ PowerShell ]

   ```
   Compress-Archive -Path .\python -DestinationPath .\layer.zip
   ```

------

   .zip ファイルのディレクトリ構造は次のようになります。

   ```
   python/     # Required top-level directory
   └── validator.py
   ```

1. 関数で、Python パッケージと同様にモジュールをインポートして使用します。例:

   ```
   from validator import validate_order, format_response
   import json
   
   def lambda_handler(event, context):
       try:
           # Parse the order data from the event body
           order_data = json.loads(event.get('body', '{}'))
           
           # Validate and format the order
           validated_order = validate_order(order_data)
           
           return format_response(200, {
               'message': 'Order validated successfully',
               'order': validated_order
           })
       except ValueError as e:
           return format_response(400, {
               'error': str(e)
           })
       except Exception as e:
           return format_response(500, {
               'error': 'Internal server error'
           })
   ```

   次の[テストイベント](testing-functions.md#invoke-with-event)を使用して関数を呼び出すことができます。

   ```
   {
       "body": "{\"product_id\": \"ABC123\", \"quantity\": 2, \"priority\": \"express\"}"
   }
   ```

   予想されるレスポンス

   ```
   {
     "statusCode": 200,
     "body": "{\"message\": \"Order validated successfully\", \"order\": {\"product_id\": \"ABC123\", \"quantity\": 2, \"shipping_priority\": \"express\"}}"
   }
   ```

## Lambda でレイヤーを作成する
<a name="publishing-layer"></a>

AWS CLI または Lambda コンソールを使用して、レイヤーを発行できます。

------
#### [ AWS CLI ]

[publish-layer-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-layer-version.html) AWS CLI コマンドを実行して Lambda レイヤーを作成します。

```
aws lambda publish-layer-version --layer-name my-layer --zip-file fileb://layer.zip --compatible-runtimes python3.14
```

[互換性のあるランタイム](https://docs.aws.amazon.com/lambda/latest/api/API_PublishLayerVersion.html#lambda-PublishLayerVersion-request-CompatibleRuntimes)パラメータの使用は任意です。指定すると、Lambda はこのパラメータを使用して Lambda コンソールのレイヤーをフィルタリングします。

------
#### [ Console ]

**レイヤーを作成するには (コンソール)**

1. Lambda コンソールの [[Layers (レイヤー)] ページ](https://console.aws.amazon.com/lambda/home#/layers)を開きます。

1. [**Create layer**] (レイヤーの作成) を選択します。

1. **[.zip ファイルをアップロードする]**を選択し、前の手順で作成しておいた .zip アーカイブをアップロードします。

1. (オプション) **[互換性のあるランタイム]**には、レイヤーの構築に使用した Python バージョンに対応する Python ランタイムを選択できます。

1. **[作成]** を選択します。

------

## レイヤーを関数に追加する
<a name="python-layer-adding"></a>

------
#### [ AWS CLI ]

レイヤーを関数にアタッチするには、[update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) AWS CLI コマンドを実行します。`--layers` パラメータには、レイヤー ARN を使用します。ARN はバージョンを指定する必要があります (`arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1` など)。詳細については、「[レイヤーとレイヤーバージョン](chapter-layers.md#lambda-layer-versions)」を参照してください。

```
aws lambda update-function-configuration --function-name my-function --cli-binary-format raw-in-base64-out --layers "arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1"
```

AWS CLI バージョン 2 を使用している場合、**cli-binary-format** オプションは必須です。これをデフォルト設定にするには、`aws configure set cli-binary-format raw-in-base64-out` を実行します。詳細については、バージョン 2 の AWS Command Line Interface ユーザーガイドの「[AWS CLI でサポートされているグローバルコマンドラインオプション](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)」を参照してください。

------
#### [ Console ]

**関数にレイヤーを追加する方法**

1. Lambda コンソールの [[関数]](https://console.aws.amazon.com/lambda/home#/functions) ページを開きます。

1. 関数を選択します。

1. **[レイヤー]** セクションまで下にスクロールし、**[レイヤーの追加]** を選択します。

1. **[レイヤーの選択]** で **[カスタムレイヤー]** を選択し、レイヤーを指定します。
**注記**  
レイヤーの作成時に[互換性のあるランタイム](https://docs.aws.amazon.com/lambda/latest/api/API_PublishLayerVersion.html#lambda-PublishLayerVersion-request-CompatibleRuntimes)を追加しなかった場合、レイヤーはここには表示されません。代わりにレイヤー ARN を指定できます。

1. **[Add]** (追加) を選択します。

------

## サンプルアプリ
<a name="python-layer-sample-app"></a>

Lambda レイヤーの使用方法のその他の例については、「AWS Lambda デベロッパーガイド」 GitHub リポジトリ内の [Layer-python](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-python) サンプルアプリケーションを参照してください。このアプリケーションは、Python ライブラリを含む 2 つのレイヤーを備えています。各レイヤーを作成したら、対応する関数をデプロイして呼び出し、それぞれのレイヤーが予想どおりに動作することを確認します。

# Lambda コンテキストオブジェクトを使用して Python 関数の情報を取得する
<a name="python-context"></a>

Lambda で関数が実行されると、コンテキストオブジェクトが[ハンドラー](python-handler.md)に渡されます。このオブジェクトは、呼び出し、関数、および実行関数に関する情報を示すメソッドおよびプロパティを提供します。コンテキストオブジェクトが関数ハンドラーに渡される方法の詳細については、「[Python の Lambda 関数ハンドラーの定義](python-handler.md)」をご参照ください。

**context メソッド**
+ `get_remaining_time_in_millis` — 実行がタイムアウトするまでの残り時間をミリ秒で返します。

**context プロパティ**
+ `function_name` － Lambda 関数の名前。
+ `function_version` － 関数の[バージョン](configuration-versions.md)。
+ `invoked_function_arn` － 関数を呼び出すために使用される Amazon リソースネーム (ARN)。呼び出し元でバージョン番号またはエイリアスが指定されているかどうかを示します。
+ `memory_limit_in_mb` － 関数に割り当てられたメモリの量。
+ `aws_request_id` － 呼び出しリクエストの ID。
+ `log_group_name` － 関数のロググループ。
+ `log_stream_name` — 関数インスタンスのログストリーム。
+ `identity` — (モバイルアプリケーション) リクエストを認可した Amazon Cognito ID に関する情報。
  + `cognito_identity_id` - 認証された Amazon Cognito ID
  + `cognito_identity_pool_id` — 呼び出しを承認した Amazon Cognito ID プール。
+ `client_context` —（モバイルアプリ）クライアントアプリケーションが Lambda に提供したクライアントコンテキスト。
  + `client.installation_id`
  + `client.app_title`
  + `client.app_version_name`
  + `client.app_version_code`
  + `client.app_package_name`
  + `custom` - モバイルクライアントアプリケーションが設定したカスタム値の `dict`。
  + `env` - `dict` SDK が提供した環境情報の AWS。

Powertools for Lambda (Python) は、Lambda コンテキストオブジェクトのインターフェイス定義を提供します。型ヒントのインターフェイス定義を使用して、Lambda コンテキストオブジェクトの構造をさらに検査したりできます。インターフェイス定義については、GitHub の *powertools-lambda-python* リポジトリの [lambda\$1context.py](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/typing/lambda_context.py) を参照してください。

以下の例は、コンテキスト情報を記録するハンドラ関数を示します。

**Example handler.py**  

```
import time

def lambda_handler(event, context):   
    print("Lambda function ARN:", context.invoked_function_arn)
    print("CloudWatch log stream name:", context.log_stream_name)
    print("CloudWatch log group name:",  context.log_group_name)
    print("Lambda Request ID:", context.aws_request_id)
    print("Lambda function memory limits in MB:", context.memory_limit_in_mb)
    # We have added a 1 second delay so you can see the time remaining in get_remaining_time_in_millis.
    time.sleep(1) 
    print("Lambda time remaining in MS:", context.get_remaining_time_in_millis())
```

上記に一覧表示するオプションに加えて、AWS 用 [AWS Lambda での Python コードの作成](python-tracing.md) X-Ray SDK を使用して、重要なコードパスの識別、パフォーマンスのトレースおよび分析のためにデータをキャプチャすることもできます。

# Python Lambda 関数のログ記録とモニタリング
<a name="python-logging"></a>

AWS Lambda は、Lambda 関数を自動的にモニタリングし、Amazon CloudWatch にログエントリを送信します。Lambda 関数には、関数のインスタンスごとに CloudWatch Logs ロググループとログストリームが用意されています。Lambda のランタイム環境は、各呼び出しの詳細や、関数のコードからのその他の出力をログストリームに送信します。CloudWatch Logs の詳細については、「[Lambda 関数ログを CloudWatch Logs に送信する](monitoring-cloudwatchlogs.md)」を参照してください。

関数コードからログを出力するには、組み込み [https://docs.python.org/3/library/logging.html](https://docs.python.org/3/library/logging.html) モジュールを使用できます。より詳細なエントリを行うため、`stdout` または `stderr` に書き込みを行う任意のログ記録ライブラリを使用できます。

## ログへの印刷
<a name="python-logging-output"></a>

基本的な出力をログに送信するには、関数の `print` メソッドを使用できます。次の例では、Amazon CloudWatch Logs のロググループとストリーム、イベントオブジェクトの値をログに記録します。

関数が Python `print` ステートメントを使用してログを出力する場合、Lambda はログ出力をプレーンテキスト形式でのみ CloudWatch Logs に送信できることに注意してください。構造化 JSON でログをキャプチャするには、サポートされているログ記録ライブラリを使用する必要があります。詳細については「[Python での Lambda の高度なログ記録コントロールの使用](#python-logging-advanced)」を参照してください。

**Example lambda\$1function.py**  

```
import os
def lambda_handler(event, context):
    print('## ENVIRONMENT VARIABLES')
    print(os.environ['AWS_LAMBDA_LOG_GROUP_NAME'])
    print(os.environ['AWS_LAMBDA_LOG_STREAM_NAME'])
    print('## EVENT')
    print(event)
```

**Example ログ出力**  

```
START RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95 Version: $LATEST
## ENVIRONMENT VARIABLES
/aws/lambda/my-function
2025/08/31/[$LATEST]3893xmpl7fac4485b47bb75b671a283c
## EVENT
{'key': 'value'}
END RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95
REPORT RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95  Duration: 15.74 ms  Billed Duration: 147 ms Memory Size: 128 MB Max Memory Used: 56 MB  Init Duration: 130.49 ms
XRAY TraceId: 1-5e34a614-10bdxmplf1fb44f07bc535a1   SegmentId: 07f5xmpl2d1f6f85 Sampled: true
```

Python ランタイムは、呼び出しごとに `START`、`END`、および `REPORT` の各行を記録します。`REPORT` 行には、次のデータが含まれています。

**REPORT 行のデータフィールド**
+ **RequestId** － 呼び出しの一意のリクエスト ID。
+ **所要時間** － 関数のハンドラーメソッドがイベントの処理に要した時間。
+ **課金期間** － 呼び出しの課金対象の時間。
+ **メモリサイズ** － 関数に割り当てられたメモリの量。
+ **使用中の最大メモリ** － 関数によって使用されているメモリの量。呼び出しが実行環境を共有すると、Lambda はすべての呼び出しで使用される最大メモリを報告します。この動作により、予想よりも高い報告値が発生する可能性があります。
+ **初期所要時間** － 最初に処理されたリクエストについて、ハンドラーメソッド外で関数をロードしてコードを実行するためにランタイムにかかった時間。
+ **XRAY TraceId** － トレースされたリクエストの場合、[AWS X-Ray のトレース ID](services-xray.md)。
+ **SegmentId** － トレースされたリクエストの場合、X-Ray のセグメント ID。
+ **サンプリング済み** － トレースされたリクエストの場合、サンプリング結果。

## ログ記録ライブラリを使用する
<a name="python-logging-lib"></a>

より詳細なログのためには、標準ライブラリ内の[ログ記録](https://docs.python.org/3/library/logging.html)モジュール、または `stdout` や `stderr` への書き込みを行うサードパーティーのログ記録ライブラリを使用します。

サポートされている Python ランタイムでは、標準 `logging` モジュールを使用して作成されたログをプレーンテキストまたは JSON のいずれかでキャプチャすることを選択できます。詳細については[Python での Lambda の高度なログ記録コントロールの使用](#python-logging-advanced)を参照してください。

現在、すべての Python ランタイムのデフォルトのログ形式はプレーンテキストです。以下の例は、標準 `logging` モジュールを使用して作成されたログ出力が CloudWatch Logs にプレーンテキストでどのようにキャプチャされるかを示しています。

```
import os
import logging
logger = logging.getLogger()
logger.setLevel("INFO")
  
def lambda_handler(event, context):
    logger.info('## ENVIRONMENT VARIABLES')
    logger.info(os.environ['AWS_LAMBDA_LOG_GROUP_NAME'])
    logger.info(os.environ['AWS_LAMBDA_LOG_STREAM_NAME'])
    logger.info('## EVENT')
    logger.info(event)
```

`logger` からの出力には、ログレベル、タイムスタンプおよびリクエスト ID が含まれています。

```
START RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125 Version: $LATEST
[INFO]  2025-08-31T22:12:58.534Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    ## ENVIRONMENT VARIABLES
[INFO]  2025-08-31T22:12:58.534Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    /aws/lambda/my-function
[INFO]  2025-08-31T22:12:58.534Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    2025/01/31/[$LATEST]1bbe51xmplb34a2788dbaa7433b0aa4d
[INFO]  2025-08-31T22:12:58.535Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    ## EVENT
[INFO]  2025-08-31T22:12:58.535Z    1c8df7d3-xmpl-46da-9778-518e6eca8125    {'key': 'value'}
END RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125
REPORT RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125  Duration: 2.75 ms   Billed Duration: 117 ms Memory Size: 128 MB Max Memory Used: 56 MB  Init Duration: 113.51 ms
XRAY TraceId: 1-5e34a66a-474xmpl7c2534a87870b4370   SegmentId: 073cxmpl3e442861 Sampled: true
```

**注記**  
関数のログ形式がプレーンテキストに設定されている場合、Python ランタイムのデフォルトのログレベル設定は WARN です。つまり、Lambda は WARN 以下のレベルのログ出力のみを CloudWatch Logs に送信します。デフォルトのログレベルを変更するには、このコード例に示すように Python `logging` `setLevel()` メソッドを使用します。関数のログ形式を JSON に設定する場合、コードのログレベルを設定するのではなく、Lambda の高度なログ制御機能を使用して関数のログレベルを設定することをお勧めします。詳細については、「[Python でのログレベルフィルタリングの使用](#python-logging-levels)」を参照してください。

## Python での Lambda の高度なログ記録コントロールの使用
<a name="python-logging-advanced"></a>

関数のログのキャプチャ、処理、使用方法をより細かく制御するために、サポートされている Lambda Python ランタイムに以下のログ記録オプションを設定できます。
+ **ログの形式** - 関数のログをプレーンテキスト形式と構造化された JSON 形式から選択します
+ **ログレベル** - JSON 形式のログの場合、Lambda が Amazon CloudWatch に送信するログの詳細レベル (ERROR、DEBUG、INFO など) を選択します。
+ **ロググループ** - 関数がログを送信する CloudWatch ロググループを選択します

これらのログ記録オプションの詳細と、それらのオプションを使用するように関数を設定する方法については、「[Lambda 関数の高度なログ記録コントロールの設定](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)」を参照してください。

Python Lambda 関数でのログ形式とログレベルオプションの使用の詳細については、以下のセクションのガイダンスをご覧ください。

### Python での構造化された JSON ログの使用
<a name="python-logging-JSON"></a>

関数のログ形式として JSON を選択した場合、Lambda は Python 標準ログ記録ライブラリによって出力されたログを構造化された JSON として CloudWatch に送信します。各 JSON ログオブジェクトには、以下のキーを含む少なくとも 4 つのキーと値のペアが含まれます。
+ `"timestamp"` - ログメッセージが生成された時刻
+ `"level"` - メッセージに割り当てられたログレベル
+ `"message"` - ログメッセージの内容
+ `"requestId"` - 関数呼び出しの一意のリクエスト ID

Python `logging` ライブラリは、この JSON オブジェクトに `"logger"` などのキーと値のペアを追加することもできます。

以下のセクションの例は、関数のログ形式を JSON として設定したときに、Python `logging` ライブラリを使用して生成されたログ出力が CloudWatch Logs にどのようにキャプチャされるかを示しています。

[ログへの印刷](#python-logging-output) で説明されているように `print` メソッドを使用して基本的なログ出力を生成する場合、関数のログ記録形式を JSON として設定した場合でも、Lambda はこれらの出力をプレーンテキストとしてキャプチャすることに注意してください。

#### Python ログ記録ライブラリを使用した標準 JSON ログ出力
<a name="python-logging-standard"></a>

以下のコードスニペットとログ出力例は、関数のログ形式が JSON に設定されている場合、Python `logging` ライブラリを使用して生成された標準ログ出力が CloudWatch Logs にどのようにキャプチャされるかを示しています。

**Example Python ログ記録コード**  

```
import logging  
logger = logging.getLogger()

def lambda_handler(event, context):
    logger.info("Inside the handler function")
```

**Example JSON ログレコード**  

```
{
    "timestamp":"2025-10-27T19:17:45.586Z",
    "level":"INFO",
    "message":"Inside the handler function",
    "logger": "root",
    "requestId":"79b4f56e-95b1-4643-9700-2807f4e68189"
}
```

#### JSON の追加パラメータの記録
<a name="python-logging-extra"></a>

関数のログ形式が JSON に設定されている場合、標準 Python `logging` ライブラリで `extra` キーワードを使用して Python ディクショナリをログ出力に渡すことで、追加のパラメータをログに記録することもできます。

**Example Python ログ記録コード**  

```
import logging

def lambda_handler(event, context):
    logging.info(
        "extra parameters example", 
        extra={"a":"b", "b": [3]},
    )
```

**Example JSON ログレコード**  

```
{
  "timestamp": "2025-11-02T15:26:28Z",
  "level": "INFO",
  "message": "extra parameters example",
  "logger": "root",
  "requestId": "3dbd5759-65f6-45f8-8d7d-5bdc79a3bd01",
  "a": "b",
  "b": [
    3
  ]
}
```

#### JSON の例外の記録
<a name="python-logging-exception"></a>

以下のコードスニペットは、ログ形式を JSON として設定した場合、Python 例外が関数のログ出力にどのようにキャプチャされるかを示しています。`logging.exception` を使用して生成されたログ出力にはログレベル ERROR が割り当てられることに注意してください。

**Example Python ログ記録コード**  

```
import logging

def lambda_handler(event, context):
    try:
        raise Exception("exception")
    except:
        logging.exception("msg")
```

**Example JSON ログレコード**  

```
{
  "timestamp": "2025-11-02T16:18:57Z",
  "level": "ERROR",
  "message": "msg",
  "logger": "root",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 15, in lambda_handler\n    raise Exception(\"exception\")\n"
  ],
  "errorType": "Exception",
  "errorMessage": "exception",
  "requestId": "3f9d155c-0f09-46b7-bdf1-e91dab220855",
  "location": "/var/task/lambda_function.py:lambda_handler:17"
}
```

#### 他のログ記録ツールでの JSON 構造化ログ
<a name="python-logging-thirdparty"></a>

コードで既に Powertools for AWS Lambda などの別のログ記録ライブラリを使用して JSON 構造化ログを生成している場合は、変更を加える必要はありません。AWS Lambda は、既に JSON でエンコードされているログを二重にエンコードしません。JSON ログ形式を使用するように関数を設定しても、ログ記録出力は定義した JSON 構造で CloudWatch に表示されます。

以下の例は、Powertools for AWS Lambda パッケージを使用して生成されたログ出力が CloudWatch Logs にどのようにキャプチャされるかを示しています。このログ出力の形式は、関数のログ記録設定が JSON であっても、TEXT であっても同じです。Powertools for AWS Lambda の使用の詳細については、「[構造化されたログ記録用の Powertools for AWS Lambda (Python) および AWS SAM を使用する](#python-logging-sam)」と「[構造化されたログ記録用の Powertools for AWS Lambda (Python) および AWS CDK を使用する](#python-logging-powertools-cdk)」を参照してください。

**Example Python ログ記録コードスニペット (Powertools for AWS Lambda を使用)**  

```
from aws_lambda_powertools import Logger

logger = Logger()

def lambda_handler(event, context):
    logger.info("Inside the handler function")
```

**Example JSON ログレコード (Powertools for AWS Lambda を使用)**  

```
{ 
    "level": "INFO", 
    "location": "lambda_handler:7", 
    "message": "Inside the handler function", 
    "timestamp": "2025-10-31 22:38:21,010+0000", 
    "service": "service_undefined", 
    "xray_trace_id": "1-654181dc-65c15d6b0fecbdd1531ecb30" 
}
```

### Python でのログレベルフィルタリングの使用
<a name="python-logging-levels"></a>

ログレベルのフィルタリングを設定することで、特定のログレベル以下のログのみを CloudWatch Logs に送信するように選択できます。関数にログレベルのフィルタリングを設定する方法については、「[ログレベルのフィルタリング](monitoring-cloudwatchlogs-log-level.md)」を参照してください。

AWS Lambda でログレベルに従ってアプリケーションログをフィルタリングするには、関数で JSON 形式のログを使用する必要があります。このためには以下の 2 つの方法があります。
+ 標準 Python `logging` ライブラリを使用してログ出力を作成し、JSON ログフォーマットを使用するように関数を設定します。その後、AWS Lambda は「[Python での構造化された JSON ログの使用](#python-logging-JSON)」で説明されている JSON オブジェクトの「level」キー値のペアを使用してログ出力をフィルタリングします。関数のログ形式を設定する方法については、「[Lambda 関数の高度なログ記録コントロールの設定](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)」を参照してください。
+ 別のログ記録ライブラリまたはメソッドを使用して、ログ出力のレベルを定義する「level」キーと値のペアを含む JSON 構造化ログをコード内に作成する。例えば、Powertools for AWS Lambda を使用してコードから JSON 構造化されたログ出力を生成できます。

  print ステートメントを使用して、ログレベル識別子を含む JSON オブジェクトを出力することもできます。以下の print ステートメントは、ログレベルが INFO に設定された JSON 形式の出力を生成します。AWS Lambda は、関数のログ記録レベルが INFO、DEBUG、または TRACE に設定されている場合、JSON オブジェクトを CloudWatch Logs に送信します。

  ```
  print('{"msg":"My log message", "level":"info"}')
  ```

Lambda で関数のログをフィルタリングするには、JSON ログ出力に `"timestamp"` のキーと値のペアも含める必要があります。時間は、有効な [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) タイムスタンプ形式で指定する必要があります。有効なタイムスタンプを指定しない場合、Lambda はログに INFO レベルを割り当ててタイムスタンプを追加します。

## Lambda コンソールでログを表示する
<a name="python-logging-console"></a>

Lambda コンソールを使用して、Lambda 関数を呼び出した後のログ出力を表示できます。

組み込み **Code** エディタからコードがテスト可能である場合、**[実行結果]** でログを確認できます。コンソールのテスト機能を使用して関数を呼び出すと、**[詳細]** セクションで **[ログ出力]** を確認できます。

## CloudWatch コンソールで ログを表示する
<a name="python-logging-cwconsole"></a>

Amazon CloudWatch コンソールを使用して、すべての Lambda 関数呼び出しのログを表示できます。

**CloudWatch コンソールでログを表示するには**

1. CloudWatch コンソールの [[Log groups (ロググループ)] ページ](https://console.aws.amazon.com/cloudwatch/home?#logs:)を開きます。

1. 機能のロググループを選択します( **/aws/lambda/*関数名***)

1. ログストリームを選択します

各ログストリームは、[関数のインスタンス](lambda-runtime-environment.md)に相当します。ログストリームは、Lambda 関数を更新したとき、および同時呼び出しを処理するために追加のインスタンスが作成されたときに表示されます。特定の呼び出しのログを検索するために、AWS X-Ray を使って関数をインストルメント化することをお勧めします。　 X-Ray は、リクエストとログストリームの詳細をトレースに記録します。

## AWS CLI でログを表示する
<a name="python-logging-cli"></a>

AWS CLI は、コマンドラインシェルでコマンドを使用して AWS サービスとやり取りするためのオープンソースツールです。このセクションの手順を完了するには、[AWS CLIバージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) が必要です。

[AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) および `--log-type` コマンドオプションを使用して、呼び出しのログを取得します。レスポンスには、`LogResult`フィールドが含まれ、このフィールドには、呼び出しから base64 コードされた最大 4 KB のログが含まれます。

**Example ログ ID を取得します**  
次の例は、`LogResult`という名前の関数の`my-function`フィールドから*ログ ID * を取得する方法を示しています。  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
次のような出力が表示されます。  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example ログをデコードします**  
同じコマンドプロンプトで、`base64` ユーティリティを使用してログをデコードします。次の例は、`my-function`の base64 でエンコードされたログを取得する方法を示しています 。  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
AWS CLI バージョン 2 を使用している場合、**cli-binary-format** オプションは必須です。これをデフォルト設定にするには、`aws configure set cli-binary-format raw-in-base64-out` を実行します。詳細については、「*AWS Command Line Interface バージョン 2 用ユーザーガイド*」の「[AWS CLI でサポートされているグローバルコマンドラインオプション](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)」を参照してください。  
以下の出力が表示されます。  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
`base64`このユーティリティは、Linux、macOS、および [ Windows の Ubuntu ](https://docs.microsoft.com/en-us/windows/wsl/install-win10) で使用できます。macOS ユーザーは、`base64 -D`を使用する必要があります 。

**Example get-logs.sh スクリプト**  
同じコマンドプロンプトで、次のスクリプトを使用して、最後の 5 つのログイベントをダウンロードします。このスクリプトは `sed` を使用して出力ファイルから引用符を削除し、ログが使用可能になるまで 15 秒待機します。この出力には Lambda からのレスポンスと、`get-log-events` コマンドからの出力が含まれます。  
次のコードサンプルの内容をコピーし、Lambda プロジェクトディレクトリに `get-logs.sh` として保存します。  
AWS CLI バージョン 2 を使用している場合、**cli-binary-format** オプションは必須です。これをデフォルト設定にするには、`aws configure set cli-binary-format raw-in-base64-out` を実行します。詳細については、「*AWS Command Line Interface バージョン 2 用ユーザーガイド*」の「[AWS CLI でサポートされているグローバルコマンドラインオプション](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)」を参照してください。  

```
#!/bin/bash
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out
sed -i'' -e 's/"//g' out
sleep 15
aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
```

**Example macOS および Linux (専用)**  
同じコマンドプロンプトで、macOS と Linux ユーザーが次のコマンドを実行して、スクリプトが実行可能であることを確認する必要があります。  

```
chmod -R 755 get-logs.sh
```

**Example 最後の 5 つのログイベントを取得します**  
同じコマンドプロンプトで、次のスクリプトを実行して、最後の 5 つのログイベントを取得します。  

```
./get-logs.sh
```
次のような出力が表示されます。  

```
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{
    "events": [
        {
            "timestamp": 1559763003171,
            "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
            "ingestionTime": 1559763003309
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r  \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r  \"key\": \"value\"\r}\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
            "ingestionTime": 1559763018353
        }
    ],
    "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
    "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
```

## ログの削除
<a name="python-logging-delete"></a>

関数を削除しても、ロググループは自動的には削除されません。ログが無期限に保存されないようにするには、ロググループを削除するか、ログが自動的に削除されるまでの[保存期間を設定](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)します。

## 他のログ記録ツールとライブラリの使用
<a name="python-tools-libraries"></a>

[Powertools for AWS Lambda (Python)](https://docs.aws.amazon.com/powertools/python/) は、サーバーレスのベストプラクティスを実装し、開発者の作業速度を向上させるための開発者ツールキットです。[ロガーユーティリティ](https://docs.aws.amazon.com/powertools/python/latest/core/logger/)は、Lambda に最適化されたロガーを提供します。このロガーは、すべての関数の関数コンテキストに関する追加情報を含み、JSON 形式で構成されて出力されます。このユーティリティを使用して次のことができます。
+ Lambda の コンテキスト、コールドスタート、構造から主要キーをキャプチャし、JSON 形式でログ出力する
+ 指示された場合 Lambda 呼び出しイベントをログ記録する (デフォルトでは無効)
+ ログサンプリングにより、特定の割合の呼び出しにのみすべてのログを出力する (デフォルトでは無効)
+ 任意のタイミングで、構造化されたログにキーを追加する
+ カスタムログフォーマッター (Bring Your Own Formatter) を使用して、組織の ログ記録 RFC と互換性のある構造でログを出力する

## 構造化されたログ記録用の Powertools for AWS Lambda (Python) および AWS SAM を使用する
<a name="python-logging-sam"></a>

以下の手順に従い、AWS SAM を使用する統合された [ Powertools for Python](https://docs.aws.amazon.com/powertools/python/latest/) モジュールを備えた Hello World Python アプリケーションのサンプルをダウンロード、構築、デプロイします。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は `hello world` のメッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ Python 3.9
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM「CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」 AWS SAM CLI のバージョンが古い場合は、「[AWS SAM CLI のアップグレード](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)」を参照してください。

**AWS SAM サンプルアプリケーションをデプロイする**

1. Hello World Python テンプレートを使用して、アプリケーションを初期化します。

   ```
   sam init --app-template hello-world-powertools-python --name sam-app --package-type Zip --runtime python3.9 --no-tracing
   ```

1. アプリケーションを構築します。

   ```
   cd sam-app && sam build
   ```

1. アプリケーションをデプロイします。

   ```
   sam deploy --guided
   ```

1. 画面に表示されるプロンプトに従ってください。インタラクティブな形式で提供されるデフォルトオプションを受け入れるには、`Enter` を押します。
**注記**  
**[HelloWorldFunction には権限が定義されていない場合がありますが、問題ありませんか？]** には、必ず `y` を入力してください。

1. デプロイされたアプリケーションの URL を取得します。

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. API エンドポイントを呼び出します。

   ```
   curl GET <URL_FROM_PREVIOUS_STEP>
   ```

   成功すると、次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. 関数のログを取得するには、[sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html) を実行します。詳細については、「AWS Serverless Application Model デベロッパーガイド」の「[ログの使用](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html)」を参照してください。

   ```
   sam logs --stack-name sam-app
   ```

   ログ出力は次のようになります。

   ```
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:50.371000 INIT_START Runtime Version: python:3.9.v16    Runtime Version ARN: arn:aws:lambda:us-east-1::runtime:07a48df201798d627f2b950f03bb227aab4a655a1d019c3296406f95937e2525
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.112000 START RequestId: d455cfc4-7704-46df-901b-2a5cce9405be Version: $LATEST
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.114000 {
     "level": "INFO",
     "location": "hello:23",
     "message": "Hello world API - HTTP 200",
     "timestamp": "2025-02-03 14:59:51,113+0000",
     "service": "PowertoolsHelloWorld",
     "cold_start": true,
     "function_name": "sam-app-HelloWorldFunction-YBg8yfYtOc9j",
     "function_memory_size": "128",
     "function_arn": "arn:aws:lambda:us-east-1:111122223333:function:sam-app-HelloWorldFunction-YBg8yfYtOc9j",
     "function_request_id": "d455cfc4-7704-46df-901b-2a5cce9405be",
     "correlation_id": "e73f8aef-5e07-436e-a30b-63e4b23f0047",
     "xray_trace_id": "1-63dd2166-434a12c22e1307ff2114f299"
   }
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.126000 {
     "_aws": {
       "Timestamp": 1675436391126,
       "CloudWatchMetrics": [
         {
           "Namespace": "Powertools",
           "Dimensions": [
             [
               "function_name",
               "service"
             ]
           ],
           "Metrics": [
             {
               "Name": "ColdStart",
               "Unit": "Count"
             }
           ]
         }
       ]
     },
     "function_name": "sam-app-HelloWorldFunction-YBg8yfYtOc9j",
     "service": "PowertoolsHelloWorld",
     "ColdStart": [
       1.0
     ]
   }
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.126000 {
     "_aws": {
       "Timestamp": 1675436391126,
       "CloudWatchMetrics": [
         {
           "Namespace": "Powertools",
           "Dimensions": [
             [
               "service"
             ]
           ],
           "Metrics": [
             {
               "Name": "HelloWorldInvocations",
               "Unit": "Count"
             }
           ]
         }
       ]
     },
     "service": "PowertoolsHelloWorld",
     "HelloWorldInvocations": [
       1.0
     ]
   }
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.128000 END RequestId: d455cfc4-7704-46df-901b-2a5cce9405be
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.128000 REPORT RequestId: d455cfc4-7704-46df-901b-2a5cce9405be    Duration: 16.33 ms    Billed Duration: 756 ms    Memory Size: 128 MB    Max Memory Used: 64 MB    Init Duration: 739.46 ms    
   XRAY TraceId: 1-63dd2166-434a12c22e1307ff2114f299    SegmentId: 3c5d18d735a1ced0    Sampled: true
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

   ```
   sam delete
   ```

### ログ保持の管理
<a name="python-log-retention"></a>

関数を削除しても、ロググループは自動的には削除されません。ログを無期限に保存しないようにするには、ロググループを削除するか、CloudWatch がログを自動的に削除するまでの保持期間を設定します。ログ保持を設定するには、AWS SAM テンプレートに以下を追加します。

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      # Omitting other properties

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${HelloWorldFunction}"
      RetentionInDays: 7
```

## 構造化されたログ記録用の Powertools for AWS Lambda (Python) および AWS CDK を使用する
<a name="python-logging-powertools-cdk"></a>

以下の手順に従い、AWS CDK を使用する統合 [Powertools for AWS Lambda (Python)](https://docs.aws.amazon.com/powertools/python/latest/) モジュールを備えた Hello World Python アプリケーションのサンプルをダウンロード、構築、デプロイします。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は「hello world」メッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ Python 3.9
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS CDK バージョン 2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites)
+ [AWS SAM「CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」 AWS SAM CLI のバージョンが古い場合は、「[AWS SAM CLI のアップグレード](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)」を参照してください。

**AWS CDK サンプルアプリケーションをデプロイする**

1. 新しいアプリケーション用のプロジェクトディレクトリを作成します。

   ```
   mkdir hello-world
   cd hello-world
   ```

1. アプリケーションを初期化します。

   ```
   cdk init app --language python
   ```

1.  Python の依存関係をインストールします。

   ```
   pip install -r requirements.txt
   ```

1. ルートフォルダーの下に **[lambda\$1function]** ディレクトリを作成します。

   ```
   mkdir lambda_function
   cd lambda_function
   ```

1. ファイル **[app.py]** を作成して、ファイルに次のコードを追加します。これは Lambda 関数のコードです。

   ```
   from aws_lambda_powertools.event_handler import APIGatewayRestResolver
   from aws_lambda_powertools.utilities.typing import LambdaContext
   from aws_lambda_powertools.logging import correlation_paths
   from aws_lambda_powertools import Logger
   from aws_lambda_powertools import Tracer
   from aws_lambda_powertools import Metrics
   from aws_lambda_powertools.metrics import MetricUnit
   
   app = APIGatewayRestResolver()
   tracer = Tracer()
   logger = Logger()
   metrics = Metrics(namespace="PowertoolsSample")
   
   @app.get("/hello")
   @tracer.capture_method
   def hello():
       # adding custom metrics
       # See: https://docs.aws.amazon.com/powertools/python/latest//latest/core/metrics/
       metrics.add_metric(name="HelloWorldInvocations", unit=MetricUnit.Count, value=1)
   
       # structured log
       # See: https://docs.aws.amazon.com/powertools/python/latest//latest/core/logger/
       logger.info("Hello world API - HTTP 200")
       return {"message": "hello world"}
   
   # Enrich logging with contextual information from Lambda
   @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
   # Adding tracer
   # See: https://docs.aws.amazon.com/powertools/python/latest//latest/core/tracer/
   @tracer.capture_lambda_handler
   # ensures metrics are flushed upon request completion/failure and capturing ColdStart metric
   @metrics.log_metrics(capture_cold_start_metric=True)
   def lambda_handler(event: dict, context: LambdaContext) -> dict:
       return app.resolve(event, context)
   ```

1. **[hello\$1world]** ディレクトリを開きます。**hello-world-stack.py** という名前のファイルが表示されます。

   ```
   cd ..
   cd hello_world
   ```

1. **hello\$1world\$1stack.py** を開き、次のコードをファイルに追加します。これには、Lambda 関数を作成し、Powertools の環境変数を構成し、ログ保持を 1 週間に設定する [Lambda コンストラクター](https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_lambda.html)と、REST API を作成する [ApiGatewayv1 コンストラクター](https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_apigateway.html) が含まれています。

   ```
   from aws_cdk import (
       Stack,
       aws_apigateway as apigwv1,
       aws_lambda as lambda_,
       CfnOutput,
       Duration
   )
   from constructs import Construct
   
   class HelloWorldStack(Stack):
   
       def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
           super().__init__(scope, construct_id, **kwargs)
   
           # Powertools Lambda Layer
           powertools_layer = lambda_.LayerVersion.from_layer_version_arn(
               self,
               id="lambda-powertools",
               # Using AWS Lambda Powertools via Lambda Layer
               # This imports the Powertools layer which provides observability features for Lambda functions
               # For available versions, see: https://docs.aws.amazon.com/powertools/python/latest/#lambda-layer
           )
   
           function = lambda_.Function(self,
               'sample-app-lambda',
               runtime=lambda_.Runtime.PYTHON_3_9,
               layers=[powertools_layer],
               code = lambda_.Code.from_asset("./lambda_function/"),
               handler="app.lambda_handler",
               memory_size=128,
               timeout=Duration.seconds(3),
               architecture=lambda_.Architecture.X86_64,
               environment={
                   "POWERTOOLS_SERVICE_NAME": "PowertoolsHelloWorld",
                   "POWERTOOLS_METRICS_NAMESPACE": "PowertoolsSample",
                   "LOG_LEVEL": "INFO"
               }
           )
   
           apigw = apigwv1.RestApi(self, "PowertoolsAPI", deploy_options=apigwv1.StageOptions(stage_name="dev"))
   
           hello_api = apigw.root.add_resource("hello")
           hello_api.add_method("GET", apigwv1.LambdaIntegration(function, proxy=True))
   
           CfnOutput(self, "apiUrl", value=f"{apigw.url}hello")
   ```

1. アプリケーションをデプロイします。

   ```
   cd ..
   cdk deploy
   ```

1. デプロイされたアプリケーションの URL を取得します。

   ```
   aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?OutputKey==`apiUrl`].OutputValue' --output text
   ```

1. API エンドポイントを呼び出します。

   ```
   curl GET <URL_FROM_PREVIOUS_STEP>
   ```

   成功すると、次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. 関数のログを取得するには、[sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html) を実行します。詳細については、「*AWS Serverless Application Model デベロッパーガイド*」の「[ログの使用](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html)」を参照してください。

   ```
   sam logs --stack-name HelloWorldStack
   ```

   ログ出力は次のようになります。

   ```
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:50.371000 INIT_START Runtime Version: python:3.9.v16    Runtime Version ARN: arn:aws:lambda:us-east-1::runtime:07a48df201798d627f2b950f03bb227aab4a655a1d019c3296406f95937e2525
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.112000 START RequestId: d455cfc4-7704-46df-901b-2a5cce9405be Version: $LATEST
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.114000 {
     "level": "INFO",
     "location": "hello:23",
       "message": "Hello world API - HTTP 200",
     "timestamp": "2025-02-03 14:59:51,113+0000",
     "service": "PowertoolsHelloWorld",
     "cold_start": true,
     "function_name": "sam-app-HelloWorldFunction-YBg8yfYtOc9j",
     "function_memory_size": "128",
     "function_arn": "arn:aws:lambda:us-east-1:111122223333:function:sam-app-HelloWorldFunction-YBg8yfYtOc9j",
     "function_request_id": "d455cfc4-7704-46df-901b-2a5cce9405be",
     "correlation_id": "e73f8aef-5e07-436e-a30b-63e4b23f0047",
     "xray_trace_id": "1-63dd2166-434a12c22e1307ff2114f299"
   }
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.126000 {
     "_aws": {
       "Timestamp": 1675436391126,
       "CloudWatchMetrics": [
         {
           "Namespace": "Powertools",
           "Dimensions": [
             [
               "function_name",
               "service"
             ]
           ],
           "Metrics": [
             {
               "Name": "ColdStart",
               "Unit": "Count"
             }
           ]
         }
       ]
     },
     "function_name": "sam-app-HelloWorldFunction-YBg8yfYtOc9j",
     "service": "PowertoolsHelloWorld",
     "ColdStart": [
       1.0
     ]
   }
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.126000 {
     "_aws": {
       "Timestamp": 1675436391126,
       "CloudWatchMetrics": [
         {
           "Namespace": "Powertools",
           "Dimensions": [
             [
               "service"
             ]
           ],
           "Metrics": [
             {
               "Name": "HelloWorldInvocations",
               "Unit": "Count"
             }
           ]
         }
       ]
     },
     "service": "PowertoolsHelloWorld",
     "HelloWorldInvocations": [
       1.0
     ]
   }
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.128000 END RequestId: d455cfc4-7704-46df-901b-2a5cce9405be
   2025/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2025-02-03T14:59:51.128000 REPORT RequestId: d455cfc4-7704-46df-901b-2a5cce9405be    Duration: 16.33 ms    Billed Duration: 756 ms    Memory Size: 128 MB    Max Memory Used: 64 MB    Init Duration: 739.46 ms    
   XRAY TraceId: 1-63dd2166-434a12c22e1307ff2114f299    SegmentId: 3c5d18d735a1ced0    Sampled: true
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

   ```
   cdk destroy
   ```

# Python での AWS Lambda 関数テスト
<a name="python-testing"></a>

**注記**  
サーバーレスソリューションをテストするためのテクニックとベストプラクティスの詳細については、「[関数のテスト](testing-guide.md)」の章を参照してください。

 サーバーレス関数のテストでは、従来のテストタイプと手法を使用しますが、サーバーレスアプリケーション全体のテストも検討する必要があります。クラウドベースのテストでは、関数とサーバーレスアプリケーションの両方の品質を**最も正確に**測定できます。

 サーバーレスアプリケーションアーキテクチャには、API 呼び出しを通じて重要なアプリケーション機能を提供するマネージドサービスが含まれます。このため、開発サイクルには、関数とサービスが相互に作用する際に機能を検証する自動テストを含める必要があります。

 クラウドベースのテストを作成しない場合、ローカル環境とデプロイされた環境の違いにより問題が発生する可能性があります。継続的な統合プロセスでは、コードをQA、ステージング、本番稼働などの次のデプロイ環境に昇格する前に、クラウドにプロビジョニングされた一連のリソースに対してテストを実行する必要があります。

 サーバーレスアプリケーションのテスト戦略に関する詳細については、このショートガイドを引き続きご覧ください。また、[サーバーレステストサンプルリポジトリ](https://github.com/aws-samples/serverless-test-samples)にアクセスして、選択した言語とランタイムに固有の実用的な例を調べることもできます。

 ![\[illustration showing the relationship between types of tests\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/test-type-illustration2.png) 

 サーバーレステストの場合も、*ユニット*テスト、*統合*テスト、*エンドツーエンド*テストを書くことになります。
+ **ユニットテスト** - 分離されたコードブロックに対して実行されるテスト。例えば、特定の商品と配送先を指定して配送料を計算するビジネスロジックを検証する場合です。
+ **統合テスト** - 通常はクラウド環境で相互作用する 2 つ以上のコンポーネントまたはサービスを対象としたテスト。例えば、キューからのイベントを処理する関数を検証する場合です。
+ **エンドツーエンドテスト** - アプリケーション全体の動作を検証するテスト。例えば、インフラストラクチャが正しくセットアップされ、顧客の注文を記録するためにイベントがサービス間で想定どおりに流れることを確認する場合です。

## サーバーレスアプリケーションのテスト
<a name="python-testing-techniques-for-serverless-applications"></a>

 通常、サーバーレスアプリケーションコードのテストには、クラウドでのテスト、モックを使ったテスト、場合によってはエミュレーターでのテストなど、さまざまな方法を組み合わせます。

### クラウドでのテスト
<a name="python-testing-in-the-cloud"></a>

 クラウドでのテストは、ユニットテスト、統合テスト、エンドツーエンドテストなど、テストのあらゆる段階で役立ちます。クラウドにデプロイされたコードやクラウドベースのサービスとやり取りするコードに対してテストを実行します。この方法では、コードの品質を**最も正確に**測定できます。

 クラウドで Lambda 関数をデバッグする便利な方法は、コンソールからテストイベントを行うことです。*テストイベント*とは、関数への JSON 入力のことです。関数が入力を必要としない場合、イベントは空の JSON ドキュメント `({})` にすることができます。コンソールには、さまざまなサービス統合のサンプルイベントが用意されています。コンソールでイベントを作成したら、それをチームと共有して、テストを簡単かつ一貫性のあるものにすることができます。

**注記**  
[コンソールで関数をテストする](testing-functions.md)のが簡単な方法ですが、テストサイクルを自動化することでアプリケーションの品質と開発スピードが保証されます。

### テストツール
<a name="python-testing-tools"></a>

 開発フィードバックのループを高速化するためのツールやテクニック。例えば、[AWS SAM Accelerate](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/accelerate.html) と [AWSCDK 監視モード](https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-deploy-watch)は、いずれもクラウド環境の更新に要する時間を短縮します。

[Moto](https://pypi.org/project/moto/) は AWS サービスやリソースを模倣するための Python ライブラリです。応答をインターセプトしてシミュレートするデコレータを使用して、ほとんどまたはまったく変更を加えずに関数をテストできます。

 [Powertools for AWS Lambda (Python)](https://docs.powertools.aws.dev/lambda-python/latest/utilities/validation/) の検証機能にはデコレータが用意されているため、Python 関数からの入力イベントと出力応答を検証できます。

 詳細については、ブログ記事「[Python と AWS モックサービスによる Lambda の単体テスト](https://aws.amazon.com/blogs/devops/unit-testing-aws-lambda-with-python-and-mock-aws-services/)」を参照してください。

 クラウドデプロイの反復に伴うレイテンシーを減らすには、「[AWS サーバーレスアプリケーションモデル (AWS SAM) アクセラレート](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-sync.html)」、「[AWS Cloud Development Kit (AWS CDK) ウォッチモード](https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-deploy-watch)」を参照してください。これらのツールは、インフラストラクチャとコードの変更を監視します。これらの変更に対応して、増分更新を自動的に作成してクラウド環境にデプロイします。

 これらのツールを使用する例は、[Python テストサンプル](https://github.com/aws-samples/serverless-test-samples/tree/main/python-test-samples)のコードリポジトリにあります。

# AWS Lambda での Python コードの作成
<a name="python-tracing"></a>

Lambda アプリケーションのトレース、デバッグ、および最適化を行うために、Lambda は AWS X-Ray と統合されています。X-Ray を使用すると、Lambda 関数や他の AWS のサービスが含まれるアプリケーション内で、リソースを横断するリクエストをトレースできます。

トレーシングデータを X-Ray に送信するには、以下に表示された 3 つの SDK ライブラリのいずれかを使用できます。
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel) – 安全で本番環境に対応し、AWS でサポートされている OpenTelemetry (OTel) SDK のディストリビューションです。
+ [AWS X-Ray SDK for Python](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-python.html) - トレースデータを生成して X-Ray に送信するための SDK です。
+ [Powertools for AWS Lambda (Python)](https://docs.aws.amazon.com/powertools/python/latest/) - サーバーレスのベストプラクティスを実装し、デベロッパーの作業速度を向上させるためのデベロッパーツールキットです。

各 SDK は、テレメトリデータを X-Ray サービスに送信する方法を提供します。続いて、X-Ray を使用してアプリケーションのパフォーマンスメトリクスの表示やフィルタリングを行い、インサイトを取得することで、問題点や最適化の機会を特定できます。

**重要**  
X-Ray および Powertools for AWS Lambda SDK は、AWS が提供する、密接に統合された計測ソリューションの一部です。ADOT Lambda レイヤーは、一般的により多くのデータを収集するトレーシング計測の業界標準の一部ですが、すべてのユースケースに適しているわけではありません。これらのソリューションのいずれかを使用して、X-Ray でエンドツーエンドのトレーシングを実装することができます。選択方法の詳細については、「[Choosing between the AWS Distro for Open Telemetry and X-Ray SDKs](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing)」( Distro for Open Telemetry または X-Ray SDK の選択) を参照してください。

**Topics**
+ [トレースに Powertools for AWS Lambda (Python) と AWS SAM を使用する](#python-tracing-sam)
+ [トレースに Powertools for AWS Lambda (Python) と AWS CDK を使用する](#python-logging-cdk)
+ [ADOT を使用して Python 関数をインストルメント化する](#python-adot)
+ [X-Ray SDK を使用して Python 関数をインストルメント化する](#python-xray-sdk)
+ [Lambda コンソールを使用してトレースを有効化する](#python-tracing-console)
+ [Lambda API でのトレースのアクティブ化](#python-tracing-api)
+ [CloudFormation によるトレースのアクティブ化](#python-tracing-cloudformation)
+ [X-Ray トレースの解釈](#python-tracing-interpretation)
+ [ランタイムの依存関係をレイヤー (X-Ray SDK) に保存する](#python-tracing-layers)

## トレースに Powertools for AWS Lambda (Python) と AWS SAM を使用する
<a name="python-tracing-sam"></a>

以下の手順に従い、AWS SAM を使用する統合 [Powertools for AWS Lambda (Python)](https://docs.powertools.aws.dev/lambda-python) モジュールを備えた Hello World Python アプリケーションのサンプルをダウンロード、構築、デプロイします。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は「hello world」メッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ Python 3.11
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 「[AWS SAM CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」 AWS SAM CLI のバージョンが古い場合は、「[AWS SAM CLI のアップグレード](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)」を参照してください。

**AWS SAM サンプルアプリケーションをデプロイする**

1. Hello World Python テンプレートを使用して、アプリケーションを初期化します。

   ```
   sam init --app-template hello-world-powertools-python --name sam-app --package-type Zip --runtime python3.11 --no-tracing
   ```

1. アプリケーションを構築します。

   ```
   cd sam-app && sam build
   ```

1. アプリケーションをデプロイします。

   ```
   sam deploy --guided
   ```

1. 画面に表示されるプロンプトに従ってください。インタラクティブな形式で提供されるデフォルトオプションを受け入れるには、`Enter` を押します。
**注記**  
**[HelloWorldFunction には権限が定義されていない場合がありますが、問題ありませんか？]** には、必ず `y` を入力してください。

1. デプロイされたアプリケーションの URL を取得します。

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. API エンドポイントを呼び出します。

   ```
   curl -X GET <URL_FROM_PREVIOUS_STEP>
   ```

   成功すると、次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. 関数のトレースを取得するには、[sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html) を実行します。

   ```
   sam traces
   ```

   トレース出力は次のようになります。

   ```
   New XRay Service Graph
     Start time: 2023-02-03 14:59:50+00:00
     End time: 2023-02-03 14:59:50+00:00
     Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [1]
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0.924
     Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: []
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0.016
     Reference Id: 2 - client - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [0]
      Summary_statistics:
        - total requests: 0
        - ok count(2XX): 0
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0
   
   XRay Event [revision 1] at (2023-02-03T14:59:50.204000) with id (1-63dd2166-434a12c22e1307ff2114f299) and duration (0.924s)
    - 0.924s - sam-app-HelloWorldFunction-YBg8yfYtOc9j [HTTP: 200]
    - 0.016s - sam-app-HelloWorldFunction-YBg8yfYtOc9j
      - 0.739s - Initialization
      - 0.016s - Invocation
        - 0.013s - ## lambda_handler
          - 0.000s - ## app.hello
      - 0.000s - Overhead
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

   ```
   sam delete
   ```

X-Ray は、アプリケーションへのすべてのリクエストをトレースするわけではありません。X-Ray は、サンプリングアルゴリズムを適用することで効率的なトレースを行うと同時に、すべてのリクエストについての代表的なサンプルを示します。サンプルレートは 1 秒あたり 1 回のリクエストで、追加リクエストの 5％ です。関数の X-Ray サンプルレートを設定することはできません。

## トレースに Powertools for AWS Lambda (Python) と AWS CDK を使用する
<a name="python-logging-cdk"></a>

以下の手順に従い、AWS CDK を使用する統合 [Powertools for AWS Lambda (Python)](https://docs.powertools.aws.dev/lambda-python) モジュールを備えた Hello World Python アプリケーションのサンプルをダウンロード、構築、デプロイします。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は「hello world」メッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ Python 3.11
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS CDK バージョン 2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites)
+ 「[AWS SAM CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」 AWS SAM CLI のバージョンが古い場合は、「[AWS SAM CLI のアップグレード](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)」を参照してください。

**AWS CDK サンプルアプリケーションをデプロイする**

1. 新しいアプリケーション用のプロジェクトディレクトリを作成します。

   ```
   mkdir hello-world
   cd hello-world
   ```

1. アプリケーションを初期化します。

   ```
   cdk init app --language python
   ```

1.  Python の依存関係をインストールします。

   ```
   pip install -r requirements.txt
   ```

1. ルートフォルダーの下に **[lambda\$1function]** ディレクトリを作成します。

   ```
   mkdir lambda_function
   cd lambda_function
   ```

1. ファイル **[app.py]** を作成して、ファイルに次のコードを追加します。これは Lambda 関数のコードです。

   ```
   from aws_lambda_powertools.event_handler import APIGatewayRestResolver
   from aws_lambda_powertools.utilities.typing import LambdaContext
   from aws_lambda_powertools.logging import correlation_paths
   from aws_lambda_powertools import Logger
   from aws_lambda_powertools import Tracer
   from aws_lambda_powertools import Metrics
   from aws_lambda_powertools.metrics import MetricUnit
   
   app = APIGatewayRestResolver()
   tracer = Tracer()
   logger = Logger()
   metrics = Metrics(namespace="PowertoolsSample")
   
   @app.get("/hello")
   @tracer.capture_method
   def hello():
       # adding custom metrics
       # See: https://docs.powertools.aws.dev/lambda-python/latest/core/metrics/
       metrics.add_metric(name="HelloWorldInvocations", unit=MetricUnit.Count, value=1)
   
       # structured log
       # See: https://docs.powertools.aws.dev/lambda-python/latest/core/logger/
       logger.info("Hello world API - HTTP 200")
       return {"message": "hello world"}
   
   # Enrich logging with contextual information from Lambda
   @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
   # Adding tracer
   # See: https://docs.powertools.aws.dev/lambda-python/latest/core/tracer/
   @tracer.capture_lambda_handler
   # ensures metrics are flushed upon request completion/failure and capturing ColdStart metric
   @metrics.log_metrics(capture_cold_start_metric=True)
   def lambda_handler(event: dict, context: LambdaContext) -> dict:
       return app.resolve(event, context)
   ```

1. **[hello\$1world]** ディレクトリを開きます。**hello-world-stack.py** という名前のファイルが表示されます。

   ```
   cd ..
   cd hello_world
   ```

1. **hello\$1world\$1stack.py** を開き、次のコードをファイルに追加します。これには、Lambda 関数を作成し、Powertools の環境変数を構成し、ログ保持を 1 週間に設定する [Lambda コンストラクター](https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_lambda.html)と、REST API を作成する [ApiGatewayv1 コンストラクター](https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_apigateway.html) が含まれています。

   ```
   from aws_cdk import (
       Stack,
       aws_apigateway as apigwv1,
       aws_lambda as lambda_,
       CfnOutput,
       Duration
   )
   from constructs import Construct
   
   class HelloWorldStack(Stack):
   
       def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
           super().__init__(scope, construct_id, **kwargs)
   
           # Powertools Lambda Layer
           powertools_layer = lambda_.LayerVersion.from_layer_version_arn(
               self,
               id="lambda-powertools",
               # At the moment we wrote this example, the aws_lambda_python_alpha CDK constructor is in Alpha, o we use layer to make the example simpler
               # See https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_lambda_python_alpha/README.html
               # Check all Powertools layers versions here: https://docs.powertools.aws.dev/lambda-python/latest/#lambda-layer
               layer_version_arn=f"arn:aws:lambda:{self.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:21"
           )
   
           function = lambda_.Function(self,
               'sample-app-lambda',
               runtime=lambda_.Runtime.PYTHON_3_11,
               layers=[powertools_layer],
               code = lambda_.Code.from_asset("./lambda_function/"),
               handler="app.lambda_handler",
               memory_size=128,
               timeout=Duration.seconds(3),
               architecture=lambda_.Architecture.X86_64,
               environment={
                   "POWERTOOLS_SERVICE_NAME": "PowertoolsHelloWorld",
                   "POWERTOOLS_METRICS_NAMESPACE": "PowertoolsSample",
                   "LOG_LEVEL": "INFO"
               }
           )
   
           apigw = apigwv1.RestApi(self, "PowertoolsAPI", deploy_options=apigwv1.StageOptions(stage_name="dev"))
   
           hello_api = apigw.root.add_resource("hello")
           hello_api.add_method("GET", apigwv1.LambdaIntegration(function, proxy=True))
   
           CfnOutput(self, "apiUrl", value=f"{apigw.url}hello")
   ```

1. アプリケーションをデプロイします。

   ```
   cd ..
   cdk deploy
   ```

1. デプロイされたアプリケーションの URL を取得します。

   ```
   aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?OutputKey==`apiUrl`].OutputValue' --output text
   ```

1. API エンドポイントを呼び出します。

   ```
   curl -X GET <URL_FROM_PREVIOUS_STEP>
   ```

   成功すると、次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. 関数のトレースを取得するには、[sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html) を実行します。

   ```
   sam traces
   ```

   トレース出力は次のようになります。

   ```
   New XRay Service Graph
     Start time: 2023-02-03 14:59:50+00:00
     End time: 2023-02-03 14:59:50+00:00
     Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [1]
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0.924
     Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: []
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0.016
     Reference Id: 2 - client - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [0]
      Summary_statistics:
        - total requests: 0
        - ok count(2XX): 0
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0
   
   XRay Event [revision 1] at (2023-02-03T14:59:50.204000) with id (1-63dd2166-434a12c22e1307ff2114f299) and duration (0.924s)
    - 0.924s - sam-app-HelloWorldFunction-YBg8yfYtOc9j [HTTP: 200]
    - 0.016s - sam-app-HelloWorldFunction-YBg8yfYtOc9j
      - 0.739s - Initialization
      - 0.016s - Invocation
        - 0.013s - ## lambda_handler
          - 0.000s - ## app.hello
      - 0.000s - Overhead
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

   ```
   cdk destroy
   ```

## ADOT を使用して Python 関数をインストルメント化する
<a name="python-adot"></a>

ADOT は、Otel SDK を使用してテレメトリデータを収集するために必要なすべてをパッケージ化した、フルマネージド型の Lambda [レイヤー](chapter-layers.md)を提供します。このレイヤーを使用すると、関数コードを変更する必要はなしで、Lambda 関数を計測できます。また、このレイヤーは、OTel でのカスタムな初期化を実行するように構成することもできます。詳細については、ADOT のドキュメントの「[Lambda 上での ADOT Collector のカスタム設定](https://aws-otel.github.io/docs/getting-started/lambda#custom-configuration-for-the-adot-collector-on-lambda)」を参照してください。

Python ランタイムの場合は、**AWS マネージド Lambda layer for ADOT Python** を追加して、関数を自動的に計測できます。このレイヤーは、arm64 アーキテクチャと x86\$164 アーキテクチャの両方で機能します。このレイヤーの使用方法の詳細については、ADOT のドキュメントの「[AWS Distro for OpenTelemetry Lambda Support for Python](https://aws-otel.github.io/docs/getting-started/lambda/lambda-python)」を参照してください。

## X-Ray SDK を使用して Python 関数をインストルメント化する
<a name="python-xray-sdk"></a>

Lambda 関数がアプリケーション内の他のリソースに対して行う呼び出しの詳細を記録するために、AWS X-Ray SDK for Python を使用することもできます。SDK を取得するには、アプリケーションの依存関係に `aws-xray-sdk` パッケージを追加します。

**Example [requirements.txt](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-python/function/requirements.txt)**  

```
jsonpickle==1.3
aws-xray-sdk==2.4.3
```

機能コードでは、`boto3` ライブラリに `aws_xray_sdk.core` モジュールをパッチすることにより、AWS SDK クライアントをインストルメント化できます。

**Example [関数 - AWS SDK クライアントのトレース](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-python/function/lambda_function.py)**  

```
import boto3
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

logger = logging.getLogger()
logger.setLevel(logging.INFO)
patch_all()

client = boto3.client('lambda')
client.get_account_settings()

def lambda_handler(event, context):
    logger.info('## ENVIRONMENT VARIABLES\r' + jsonpickle.encode(dict(**os.environ)))
  ...
```

正しい依存関係を追加し、必要なコード変更を行った後、Lambda コンソールまたは API を介して関数の設定でトレースをアクティブにします。

## Lambda コンソールを使用してトレースを有効化する
<a name="python-tracing-console"></a>

コンソールを使用して、Lambda 関数のアクティブトレースをオンにするには、次のステップに従います。

**アクティブトレースをオンにするには**

1. Lambda コンソールの [[関数ページ]](https://console.aws.amazon.com/lambda/home#/functions) を開きます。

1. 関数を選択します。

1. **[設定]** を選択してから、**[モニタリングおよび運用ツール]** を選択します。

1. **[その他の監視ツール]** で、**[編集]** を選択します。

1. **[CloudWatch Application Signals と AWS X-Ray]** で、**[Lambda サービストレース]** の **[有効]** を選択します。

1. **[保存]** を選択します。

## Lambda API でのトレースのアクティブ化
<a name="python-tracing-api"></a>

AWS CLI または AWS SDK で Lambda 関数のトレースを設定するには、次の API オペレーションを使用します。
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)

以下の例の AWS CLI コマンドは、**my-function** という名前の関数に対するアクティブトレースを有効にします。

```
aws lambda update-function-configuration --function-name my-function \
--tracing-config Mode=Active
```

トレースモードは、関数のバージョンを公開するときのバージョン固有の設定の一部です。公開後のバージョンのトレースモードを変更することはできません。

## CloudFormation によるトレースのアクティブ化
<a name="python-tracing-cloudformation"></a>

CloudFormation テンプレート内で `AWS::Lambda::Function` リソースに対するアクティブトレースを有効化するには、`TracingConfig` プロパティを使用します。

**Example [function-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml) － トレース設定**  

```
Resources:
  function:
    Type: [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
    Properties:
      TracingConfig:
        Mode: Active
      ...
```

AWS Serverless Application Model (AWS SAM) `AWS::Serverless::Function` リソースに、`Tracing` プロパティを使用します。

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml) － トレース設定**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Tracing: Active
      ...
```

## X-Ray トレースの解釈
<a name="python-tracing-interpretation"></a>

関数には、トレースデータを X-Ray にアップロードするためのアクセス許可が必要です。Lambda コンソールでトレースを有効にすると、Lambda は必要な権限を関数の [[実行ロール]](lambda-intro-execution-role.md) に追加します。それ以外の場合は、[AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) ポリシーを実行ロールに追加します。

アクティブトレースの設定後は、アプリケーションを通じて特定のリクエストの観測が行えるようになります。[[X-Ray サービスグラフ]](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph) には、アプリケーションとそのすべてのコンポーネントに関する情報が表示されます。次の例は、2 つの関数を持つアプリケーションを示しています。プライマリ関数はイベントを処理し、エラーを返す場合があります。上位 2 番目の関数は、最初のロググループに表示されるエラーを処理し、AWS SDK を使用して X-Ray、Amazon Simple Storage Service (Amazon S3)、および Amazon CloudWatch Logs を呼び出します。

![\[\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/sample-errorprocessor-servicemap.png)


X-Ray は、アプリケーションへのすべてのリクエストをトレースするわけではありません。X-Ray は、サンプリングアルゴリズムを適用することで効率的なトレースを行うと同時に、すべてのリクエストについての代表的なサンプルを示します。サンプルレートは 1 秒あたり 1 回のリクエストで、追加リクエストの 5％ です。関数の X-Ray サンプルレートを設定することはできません。

X-Ray では、*トレース*は 1 つ以上の*サービス*によって処理されるリクエストに関する情報を記録します。Lambda はトレースごとに 2 つのセグメントを記録します。これにより、サービスグラフに 2 つのノードが作成されます。次の図は、これら 2 つのノードを強調表示しています。

![\[\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/xray-servicemap-function.png)


左に示された 1 つめのノードは、呼び出しリクエストを受信する Lambda サービスを表しています。2 つめのノードは、特定の Lambda 関数を表しています。次の例は、これら 2 つのセグメントを使用したトレースを示しています。いずれも **my-function** と名付けられていますが、1 つは `AWS::Lambda` の起点があり、もう 1 つは `AWS::Lambda::Function` の起点があります。`AWS::Lambda` セグメントにエラーが表示される場合は、Lambda サービスに問題があります。`AWS::Lambda::Function` セグメントにエラーが表示される場合、関数に問題があります。

![\[\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/V2_sandbox_images/my-function-2-v1.png)


この例では、`AWS::Lambda::Function` セグメントを展開して、それの 3 つのサブセグメントが表示されています。

**注記**  
AWS は現在、Lambda サービスに変更を実装しています。これらの変更により、AWS アカウント のさまざまな Lambda 関数によって出力されるシステムログメッセージとトレースセグメントの構造と内容にわずかな違いが生じる場合があります。  
ここで示すトレースの例は、古いスタイルの関数セグメントを示しています。古いスタイルのセグメントと新しいスタイルのセグメントの違いについては、次の段落で説明します。  
これらの変更は今後数週間に実装され、中国および GovCloud リージョンを除くすべての AWS リージョンのすべての関数は、新しい形式のログメッセージとトレースセグメントを使用するように移行されます。

古いスタイルの関数セグメントには、次のサブセグメントが含まれます。
+ **初期化** － 関数のロードと[初期化コード](foundation-progmodel.md)の実行に要した時間を表します。このサブセグメントは、関数の各インスタンスが処理する最初のイベントに対してのみ表示されます。
+ **[呼び出し]** - ハンドラーコードの実行に要した時間を表します。
+ **[オーバーヘッド]** - Lambda ランタイムが次のイベントを処理するための準備に要する時間を表します。

新しいスタイルの関数セグメントには `Invocation` サブセグメントが含まれていません。代わりに、顧客サブセグメントが関数セグメントに直接アタッチされます。古いスタイルの関数セグメントと新しいスタイルの関数セグメントの構造の詳細については、「」を参照してください[X-Ray トレースを理解する](services-xray.md#services-xray-traces)。

HTTP クライアントをインストルメント化し、SQL クエリを記録して、注釈とメタデータからカスタムサブセグメントを作成することもできます。詳細については、「AWS X-Ray デベロッパーガイド」の「[AWS X-Ray SDK for Python](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-python.html)」を参照してください。

**料金**  
X-Ray トレースは、毎月、AWS 無料利用枠で設定された一定限度まで無料で利用できます。X-Ray の利用がこの上限を超えた場合は、トレースによる保存と取得に対する料金が発生します。詳細については、「[AWS X-Ray 料金表](https://aws.amazon.com/xray/pricing/)」を参照してください。

## ランタイムの依存関係をレイヤー (X-Ray SDK) に保存する
<a name="python-tracing-layers"></a>

X-Ray SDK を使用して AWS SDK クライアントを関数コードに埋め込むと、デプロイパッケージが巨大になる可能性があります。関数コードを更新するたびにランタイムの依存関係がアップロードされないようにするには、X-Ray SDK を「[Lambda レイヤー](chapter-layers.md)」にパッケージ化します。

次に、AWS X-Ray SDK for Python を保存している `AWS::Serverless::LayerVersion` リソースの例を示します。

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-python/template.yml) － 依存関係レイヤー**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      CodeUri: function/.
      Tracing: Active
      Layers:
        - !Ref libs
      ...
  libs:
    Type: [AWS::Serverless::LayerVersion](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-layerversion.html)
    Properties:
      LayerName: blank-python-lib
      Description: Dependencies for the blank-python sample app.
      ContentUri: package/.
      CompatibleRuntimes:
        - python3.11
```

この設定では、ランタイム依存関係を変更した場合にのみ、ライブラリレイヤーの更新が必要です。関数のデプロイパッケージにはユーザーのコードのみが含まれるため、アップロード時間を短縮できます。

依存関係のレイヤーを作成するには、デプロイ前にレイヤーアーカイブを生成するようにビルドを変更する必要があります。実際の例については、[blank-python](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-python) サンプルアプリケーションを参照してください。