

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Python 建置 Lambda 函數
<a name="lambda-python"></a>

您可以在 AWS Lambda中執行 Python 程式碼。Lambda 提供用於執行程式碼來處理事件的 Python [執行期](lambda-runtimes.md)。您的程式碼會在包含 SDK for Python (Boto3) 的環境中執行，其中包含您管理之 AWS Identity and Access Management (IAM) 角色的登入資料。若要進一步了解 Python 執行時期隨附的 SDK 版本，請參閱 [包含執行時期的 SDK 版本](#python-sdk-included)。

Lambda 支援以下 Python 執行期。


| Name | 識別符 | 作業系統 | 取代日期 | 封鎖函數建立 | 封鎖函數更新 | 
| --- | --- | --- | --- | --- | --- | 
|  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. 選擇**建立函數**。

1. 進行下列設定：
   + **函數名稱**：輸入函數名稱。
   + **執行時間**：選擇 **Python 3.14。**

1. 選擇**建立函數**。

主控台將建立一個 Lambda 函數，其具有名為 `lambda_function` 的單一來源檔案。您可以使用內建的程式碼編輯器編輯該檔案並加入更多檔案。在 **DEPLOY** 區段中，選擇**部署**以更新函數的程式碼。然後，若要執行程式碼，請在**測試事件**區段中選擇**建立測試事件**。

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)
+ [使用 .zip 封存檔部署 Python Lambda 函數](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)
+ [在 中檢測 Python 程式碼 AWS Lambda](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>

下表列出在適用於 Python 的 Lambda 受管執行期和容器基礎映像中停用的 Python 功能。編譯 Python 執行時間可執行檔時，必須啟用這些功能，且無法使用執行時間旗標啟用。若要在 Lambda 中使用這些功能，您可以使用[容器映像](python-image.md#python-image-clients)或[自訂執行期，在啟用這些功能的情況下部署自己的 Python 執行期](runtimes-custom.md)組建。


| 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 回應包含 Unicode 字元。早期版本 Python 的執行期會在回應中傳回 Unicode 字元的逸出序列。例如，在 Python 3.11 中，如果您傳回 Unicode 字串，如 "こんにちは"，它將逸出 Unicode 字元並傳回 "\$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 範例 GitHub 儲存庫](https://github.com/aws-samples/graceful-shutdown-with-aws-lambda)。

# 以 Python 定義 Lambda 函數處理常式
<a name="python-handler"></a>

Lambda 函數*處理常式*是您的函數程式碼中處理事件的方法。當有人呼叫您的函數時，Lambda 會執行處理常式方法。函數會執行，直到處理常式傳回回應、結束或逾時為止。

本頁介紹了如何在 Python 中使用 Lambda 函式處理常式，包括命名慣例、有效的處理常式簽章及程式碼最佳實務。本頁還提供了一個 Python Lambda 函式範例，該函式會取得訂單的相關資訊、產生文字檔案收據，並將此檔案放入 Amazon Simple Storage Service (Amazon S3) 儲存貯體。

**Topics**
+ [Python Lambda 函式程式碼範例](#python-handler-example)
+ [處理常式命名慣例](#python-handler-naming)
+ [使用 Lambda 事件物件](#python-handler-event)
+ [存取和使用 Lambda 內容物件](#python-handler-context)
+ [Python 處理常式的有效處理常式簽章](#python-handler-signature)
+ [傳回值](#python-handler-return)
+ [在處理常式中使用 適用於 Python (Boto3) 的 AWS SDK](#python-handler-sdk)
+ [存取環境變數](#python-handler-env-vars)
+ [Python Lambda 函數的程式碼最佳實務](#python-handler-best-practices)

## Python Lambda 函式程式碼範例
<a name="python-handler-example"></a>

以下 Python 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)會傳遞兩個引數至該函式：其一為包含函式需處理之資料的[事件物件](#python-handler-event)，另一為包含函式調用相關資訊的[內容物件](#python-handler-context)。

## 處理常式命名慣例
<a name="python-handler-naming"></a>

建立 Lambda 函式時定義的 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 物件。事件物件的確切格式取決於調用函式的服務。若要檢視特定服務的事件格式，請參閱[使用來自其他服務的事件叫用 Lambda AWS](lambda-services.md)章節中的對應頁面。

如果輸入事件採用 JSON 物件的形式，Lambda 執行時期會將物件轉換為 Python 字典。若要將輸入 JSON 中的值指派給程式碼中的變數，請如程式碼範例所示，採用標準的 Python 字典方法。

您也可以將資料作為 JSON 陣列或任何其他有效的 JSON 資料類型傳遞至函式。下表定義了 Python 執行時期如何轉換這些 JSON 類型。


| JSON 資料類型 | Python 資料類型 | 
| --- | --- | 
| object | 字典 (dict) | 
| 陣列 | 清單 (list) | 
| number | 整數 (int) 或浮點數 (float) | 
| string | 字串 (str) | 
| Boolean | 布林值 (bool) | 
| null | 空類型 (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 中定義處理常式函式時，函式必須採用兩個引數。第一個引數是 Lambda [事件物件](#python-handler-event)，第二個引數是 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 服務產生的事件以及內容物件使用特定的 AWS 類型，請將 `aws-lambda-typing` 套件新增至函式的部署套件。您可以透過執行 `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]:
```

您無法將 Python `async` 函式類型用於處理常式函式。

## 傳回值
<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` (如沒有 `return` 陳述式的 Python 函數隱含作業)，則執行時間會傳回 `null`。
+ 如果使用 `Event` 調用類型 ([非同步調用](invocation-async.md))，便會捨棄該值。

在範例程式碼中，處理常式會傳回下列 Python 字典：

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

Lambda 執行時期會將此字典序列化，並將其作為 JSON 字串傳回給調用該函式的用戶端。

**注意**  
在 Python 3.9 及更高版本中，Lambda 會在錯誤回應中包含調用的請求 ID。

## 在處理常式中使用 適用於 Python (Boto3) 的 AWS SDK
<a name="python-handler-sdk"></a>

通常，您會使用 Lambda 函式與其他 AWS 服務和資源互動。與這些資源互動的最簡單方法便是使用 適用於 Python (Boto3) 的 AWS SDK。所有[支援的 Lambda Python 執行時期](lambda-runtimes.md#runtimes-supported)都包含適用於 Python 的 SDK 版本。但是，如果程式碼需要使用 SDK，強烈建議在函式的部署套件中包含該 SDK。在部署套件中包含 SDK 可讓您完全控制相依項，並降低與其他程式庫發生版本不一致問題的風險。如需進一步了解，請參閱 [Python 中的執行期相依項](python-package.md#python-package-dependencies) 和 [回溯相容性](runtimes-update.md#runtime-update-compatibility)。

若要在 Lambda 函式中使用適用於 Python 的 SDK，請將下列陳述式新增至函式程式碼開頭的 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 參考](https://docs.aws.amazon.com/lambda/latest/api/welcome.html)查看公開可用 API 的清單。

**撰寫等冪程式碼。**為函數撰寫等冪程式碼可確保採用相同方式來處理重複事件。程式碼應正確驗證事件並正常處理重複的事件。如需詳細資訊，請參閱 [How do I make my Lambda function idempotent?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/) (如何讓 Lambda 函數等冪？)。

# 使用 .zip 封存檔部署 Python Lambda 函數
<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 檔案公用程式 (例如 [7zip](https://www.7-zip.org/download.html))。以下各節顯示的範例假設您在 Linux 或 MacOS 環境中使用命令列 `zip` 工具。若要在 Windows 中使用相同命令，您可以[安裝適用於 Linux 的 Windows 子系統](https://docs.microsoft.com/en-us/windows/wsl/install-win10)，以取得 Ubuntu 和 Bash 的 Windows 整合版本。

 請注意，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 執行時間包含 適用於 Python (Boto3) 的 AWS SDK 及其相依性。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 公用程式建立 .zip 檔案，並將 .py 檔案放在根目錄下。如果 .py 檔案不在 .zip 檔案的根目錄下，Lambda 將無法執行您的程式碼。

 若要了解如何部署 .zip 檔案以建立新的 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. 建立名為 package 的新目錄，您將在其中安裝相依項。

   ```
   mkdir package
   ```

   請注意，對於 .zip 部署套件，Lambda 預期您的原始程式碼及其相依項全部位於 .zip 檔案的根目錄。不過，直接在專案目錄中安裝相依項可能會產生大量新檔案和資料夾，並使導覽 IDE 變得困難。您可以在此處建立單獨的 `package` 目錄，將您的相依項與原始程式碼分開。

1. 在 `package` 目錄中安裝您的相依項。以下範例使用 pip 從 Python Package Index 安裝 Boto3 SDK。如果您的函數程式碼使用您自己建立的 Python 套件，請將其儲存在 `package` 目錄中。

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

1. 建立 .zip 檔案，將已安裝的程式庫放在根目錄下。

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

   這會在專案目錄中產生 `my_deployment_package.zip` 檔案。

1. 將 lambda\$1function.py 檔案新增至 .zip 檔案的根目錄

   ```
   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 開發套件及其相依性會安裝在 `/var/lang/lib/python3.11/site-packages`目錄中。

 您可以新增下列程式碼片段，以查看 Lambda 函數的完整搜尋路徑。

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

**注意**  
由於部署套件或圖層中的相依項優先於含執行期程式庫，因此如果您在套件中包含 urllib3 這類 SDK 相依項而不同時包含 SDK 的話，則可能會造成版本不相容問題。如果您部署自己的 Boto3 相依項版本，則還必須在部署套件中部署 Boto3 作為相依項。我們建議您封裝函數的所有相依項，即使其版本包含在執行期中。

 您也可以在 .zip 套件內的個別資料夾中新增相依項。例如，您可以將 Boto3 SDK 的版本新增至名為 `common` 的 .zip 套件中的資料夾。解壓縮並掛載您的 .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 檔案。許多主流 Python 程式庫 (包括 NumPy 和 Pandas) 都不是純 Python，且包含以 C 或 C\$1\$1 編寫的程式碼。將包含 C/C\$1\$1 程式碼的程式庫新增至部署套件時，必須正確建置套件，以確保套件與 Lambda 執行環境相容。

 Python Package Index ([PyPI](https://pypi.org/))上提供的大多數套件都可以作為「wheel」(.whl 檔案)。.whl 檔案是一種 ZIP 檔案，其中的內建發佈包含針對特定作業系統和指令集架構預先編譯的二進位檔。若要讓您的部署套件與 Lambda 相容，請安裝適用於 Linux 作業系統和您函數指令集架構的 wheel。

 某些套件可能只能作為原始檔發佈。對於這些套件，您需要自行編譯和建置 C/C\$1\$1 元件。

 若要查看所需套件可用的發佈，請執行以下操作：

1. 在 [Python Package Index 主頁](https://pypi.org/)上搜尋套件名稱。

1. 選擇您要使用的套件版本。

1. 選擇**下載檔案**。

### 使用內建發佈 (wheel)
<a name="python-package-wheels"></a>

 若要下載與 Lambda 相容的 wheel，請使用 pip `--platform` 選項。

 如果您的 Lambda 函數使用 **x86\$164** 指令集架構，請執行下列 `pip install` 命令，在 `package` 目錄中安裝相容的 wheel。以您所使用的 Pytho 執行期版本取代 `--python 3.x`。

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

 如果您的函數使用 **arm64** 指令集架構，請執行下列命令。以您所使用的 Pytho 執行期版本取代 `--python 3.x`。

```
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 User Guide* 中的 [Get started with 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 函數或更新現有函數。您可以使用 Lambda 主控台、 AWS Command Line Interface和 Lambda API 部署 .zip 套件。您也可以使用 AWS Serverless Application Model  (AWS SAM) 和  CloudFormation 建立並更新 Lambda 函數。

Lambda 的 .zip 部署套件大小上限為 250 MB (解壓縮)。請注意，此限制適用於您上傳的所有檔案 (包括任何 Lambda 層) 的大小總和。

Lambda 執行時間需有許可才能讀取部署套裝服務中的檔案。在 Linux 許可八進位標記法中，Lambda 需要 644 個許可 (rw-r--r--) 用於非可執行檔，以及 755 個許可 (rwxr-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，您可以透過直接從本機電腦上傳檔案來建立或更新函數。若 .zip 檔案大於 50 MB，您必須先將套件上傳至 Amazon S3 儲存貯體。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的說明 AWS 管理主控台，請參閱 [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. 選擇 **Author from scratch** (從頭開始撰寫)。

1. 在**基本資訊**下，請執行下列動作：

   1. 在**函數名稱**中輸入函數名稱。

   1. 在**執行期**中選取要使用的執行期。

   1. (選用) 在**架構**中選擇要用於函數的指令集架構。預設架構值為 x86\$164。請確定函數的 .zip 部署套件與您選取的指令集架構相容。

1. (選用) 在**許可**下，展開**變更預設執行角色**。您可建立新的**執行角色**，或使用現有的角色。

1. 選擇 **Create function (建立函數)**。Lambda 會使用您選擇的執行期建立一個基本的「Hello world」函數。

**若要從本機電腦上傳 .zip 封存檔 (主控台)**

1. 在 Lambda 主控台的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)中選擇要上傳 .zip 檔案的函數。

1. 選取**程式碼**索引標籤。

1. 在**程式碼來源**窗格中選擇**上傳來源**。

1. 選擇 **.zip 檔案**。

1. 若要上傳 .zip 檔案，請執行下列操作：

   1. 選擇**上傳**，然後在檔案選擇器中選取您的 .zip 檔案。

   1. 選擇 **Open** (開啟)。

   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/zh_tw/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

### 使用 建立和更新具有 .zip 檔案的函數 AWS CLI
<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 套件。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的說明 AWS CLI，請參閱*AWS CLI 《 使用者指南*》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
如果您使用 從 Amazon S3 儲存貯體上傳 .zip 檔案 AWS CLI，儲存貯體必須與 AWS 區域 函數位於相同的 中。

 若要搭配 使用 .zip 檔案建立新的函數 AWS CLI，您必須指定下列項目：
+ 函數名稱 (`--function-name`)
+ 函數的執行期 (`--runtime`)
+ 函數[執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)的 Amazon Resource Name (ARN) (`--role`)
+ 函數程式碼中處理常式方法的名稱 (`--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)

### 使用 建立和更新具有 .zip 檔案的函數 AWS SAM
<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 開發人員指南*》中的 [入門 AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html)。

您也可以使用 AWS SAM 來建立使用現有 .zip 檔案封存的 Lambda 函數。若要使用 建立 Lambda 函數 AWS SAM，您可以將 .zip 檔案儲存在 Amazon S3 儲存貯體或建置機器的本機資料夾中。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的說明 AWS CLI，請參閱*AWS CLI 《 使用者指南*》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

 在您的 AWS SAM 範本中，`AWS::Serverless::Function`資源會指定您的 Lambda 函數。在本資源中設定下列屬性，以使用 .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 檔案大於 50MB，則不需要先將其上傳至 Amazon S3 儲存貯體。 AWS SAM 可以從本機建置機器的位置上傳最大允許大小為 250MB （解壓縮） 的 .zip 套件。

 若要進一步了解如何在 中使用 .zip 檔案部署函數 AWS SAM，請參閱《 *AWS SAM 開發人員指南*》中的 [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)。

### 使用 建立和更新具有 .zip 檔案的函數 CloudFormation
<a name="python-package-create-cfn"></a>

 您可以使用 CloudFormation 建立使用 .zip 檔案封存的 Lambda 函數。若要使用 .zip 檔案建立 Lambda 函數，您必須先將檔案上傳至 Amazon S3 儲存貯體。如需如何使用 將檔案上傳至 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 *

對於 Node.js 和 Python 執行期，您也可以在 CloudFormation 範本中提供內嵌原始程式碼。 CloudFormation 然後，當您建置函數時， 會建立包含程式碼的 .zip 檔案。

**使用現有的 .zip 檔案**

在您的 CloudFormation 範本中，`AWS::Lambda::Function`資源會指定您的 Lambda 函數。在本資源中設定下列屬性，以使用 .zip 封存檔建立函數：
+ `PackageType`：設定為 `Zip`
+ `Code`：在 `S3Bucket` 和 `S3Key` 欄位中輸入 Amazon S3 儲存貯體名稱和 .zip 檔案名稱。
+ `Runtime`：設定為所選執行期

**從內嵌程式碼建立 .zip 檔案**

您可以在 CloudFormation 範本中宣告以 Python 或 Node.js 內嵌撰寫的簡單函數。由於程式碼內嵌在 YAML 或 JSON 中，因此您無法將任何外部相依項新增至部署套件。這表示您的函數必須使用 執行時間中包含的 AWS SDK 版本。範本的需求 (例如必須逸出某些字元) 也會讓使用 IDE 的語法檢查和程式碼完成功能變得更加困難。也就是說，您的範本可能需要進行其他測試。由於這些限制，宣告函數內嵌程式碼最適合非常簡單且不會頻繁變更的程式碼。

若要從 Node.js 和 Python 執行期的內嵌程式碼建立 .zip 檔案，請在範本的 `AWS::Lambda::Function` 資源中設定下列屬性：
+ `PackageType`：設定為 `Zip`
+ `Code`：在 `ZipFile` 欄位中輸入您的函數程式碼
+ `Runtime`：設定為所選執行期

 CloudFormation 產生的 .zip 檔案不能超過 4MB。若要進一步了解如何在 中使用 .zip 檔案部署函數 CloudFormation，請參閱*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 函數建置容器映像：
+ [使用 Python AWS 的基礎映像](#python-image-instructions)

  [AWS  基礎映像](images-create.md#runtimes-images-lp)會預先載入語言執行期、用來管理 Lambda 與函數程式碼之間互動的執行期界面用戶端，以及用於本機測試的執行期界面模擬器。
+ [使用僅限 AWS 作業系統的基礎映像](images-create.md#runtimes-images-provided)

  [AWS 僅限作業系統的基礎映像](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) 建置容器映像。您還可以使用僅限作業系統的基礎映像來實作[自訂執行期](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**
+ [AWS Python 的基礎映像](#python-image-base)
+ [使用 Python AWS 的基礎映像](#python-image-instructions)
+ [透過執行期介面用戶端使用替代基礎映像](#python-image-clients)

## AWS Python 的基礎映像
<a name="python-image-base"></a>

AWS 為 Python 提供下列基礎映像：


| Tags (標籤) | 執行期 | 作業系統 | 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 | [Dockerfile for Python 3.13 on GitHub](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 | [Dockerfile for Python 3.12 on GitHub](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 | [Dockerfile for Python 3.11 on GitHub](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 | [Dockerfile for Python 3.10 on GitHub](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 映像為基礎。與 Amazon Linux 2 相比，以 AL2023 為基礎的映像具有多項優點，包括更小的部署足跡和更新版本的程式庫，如 `glibc`。

以 AL2023 為基礎的映像使用 `microdnf` (符號連結為 `dnf`) 而不是 `yum` 作為套件管理工具，後者是 Amazon Linux 2 中的預設套件管理工具。`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/)。

**注意**  
若要在本機執行AL2023-based映像，包括搭配 AWS Serverless Application Model (AWS SAM)，您必須使用 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` 的新檔案。如果您使用上一個步驟的範例函數程式碼，請將檔案保留空白，因為沒有任何相依項。否則，請列出每個所需的程式庫。例如，如果您的函數使用  適用於 Python (Boto3) 的 AWS SDK，您的 `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 時，Lambda 會自動定義一個具有最低權限許可的預設 Linux 使用者。這與標準 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 build](https://docs.docker.com/engine/reference/commandline/build/) 命令建立 Docker 映像檔。以下範例將映像命名為 `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 .
   ```
**注意**  
此命令會指定 `--platform linux/amd64` 選項，確保無論建置機器的架構為何，您的容器都與 Lambda 執行環境相容。如果您打算使用 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/arm64`選項改用選項。`--platform linux/amd64`

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`值設定為您要 AWS 區域 在其中建立 Amazon ECR 儲存庫的 。
   + `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 Resource Name (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 函數，必須使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令，即使 Amazon ECR 中的映像標籤保持不變亦如此。在以下範例中，`--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>

如果您使用[僅限作業系統的基礎映像](images-create.md#runtimes-images-provided)或替代的基礎映像，則必須在映像中加入執行期介面用戶端。執行期介面用戶端會讓您擴充 [Runtime API](runtimes-api.md)，管理 Lambda 與函數程式碼之間的互動。

使用 pip 套件管理員安裝 [Python 執行期介面用戶端](https://pypi.org/project/awslambdaric)。

```
pip install awslambdaric
```

您還可以從 GitHub 下載 [Python 執行時間介面用戶端](https://github.com/aws/aws-lambda-python-runtime-interface-client/)。

下列範例示範如何使用非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` 的新檔案。如果您使用上一個步驟的範例函數程式碼，請將檔案保留空白，因為沒有任何相依項。否則，請列出每個所需的程式庫。例如，如果您的函數使用  適用於 Python (Boto3) 的 AWS SDK，您的 `requirements.txt` 看起來應該像這樣：  
**Example requirements.txt**  

   ```
   boto3
   ```

1. 建立新的 Dockerfile。下列 Dockerfile 使用官方 Python 基礎映像，而非 [AWS  基礎映像](images-create.md#runtimes-images-lp)。Dockerfile 包含[執行期介面用戶端](https://pypi.org/project/awslambdaric)，可讓映像與 Lambda 相容。下列範例 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 時，Lambda 會自動定義一個具有最低權限許可的預設 Linux 使用者。這與標準 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 build](https://docs.docker.com/engine/reference/commandline/build/) 命令建立 Docker 映像檔。以下範例將映像命名為 `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 .
   ```
**注意**  
此命令會指定 `--platform linux/amd64` 選項，確保無論建置機器的架構為何，您的容器都與 Lambda 執行環境相容。如果您打算使用 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` 是 Dockerfile 中的 `ENTRYPOINT`，後面接著 `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/arm64`選項改用選項。`--platform linux/amd64`

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`值設定為您要 AWS 區域 在其中建立 Amazon ECR 儲存庫的 。
   + `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 Resource Name (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 函數，必須使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令，即使 Amazon ECR 中的映像標籤保持不變亦如此。在以下範例中，`--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)或組態檔案。建立層包含三個一般步驟：

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 建置 layer，請使用適用於函數的 Python 3.14 執行時間。
+ .zip 檔案必須在根層級包含 `python` 目錄。
+ 層中的套件必須與 Linux 相容。Lambda 函式會在 Amazon Linux 上執行。

您可以建立包含透過 `pip` 安裝的第三方 Python 程式庫 (例如 `requests` 或 `pandas`) 的層，或您自訂的 Python 模組與套件的層。

### 第三方相依性
<a name="python-layers-third-party-dependencies"></a>

**使用 pip 套件建立層**

1. 選擇下列其中一種方法，將 `pip` 套件安裝到所需的頂層目錄 (`python/`)：

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

   對於純 Python 套件 (如 requests 或 boto3)：

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

   部分 Python 套件 (如 NumPy 與 Pandas) 包含經編譯的 C 元件。如果您在 macOS 或 Windows 上建置包含這些套件的層，可能需要使用此命令來安裝與 Linux 相容的 wheel：

   ```
   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 套件 (如 requests 或 boto3)：

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

   部分 Python 套件 (如 NumPy 與 Pandas) 包含經編譯的 C 元件。如果您在 macOS 或 Windows 上建置包含這些套件的層，可能需要使用此命令來安裝與 Linux 相容的 wheel：

   ```
   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 主控台發佈 layer。

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

執行 [publish-layer-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-layer-version.html) AWS CLI 命令來建立 Lambda layer：

```
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 主控台中的 [層頁面](https://console.aws.amazon.com/lambda/home#/layers)。

1. 選擇 **建立圖層**。

1. 選擇**上傳 .zip 檔案**，然後上傳先前建立的 .zip 壓縮檔。

1. (選用) 在**相容的執行時期**欄位中，選擇與用於建置層的 Python 版本相對應的 Python 執行時期。

1. 選擇**建立**。

------

## 將層新增至函式
<a name="python-layer-adding"></a>

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

若要將 layer 連接至函數，請執行 [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"
```

如果您使用的是第 2 AWS CLI 版，則需要 **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)。

------
#### [ 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. 選擇**新增**。

------

## 應用程式範例
<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 程式庫的層。建立層之後，您可以部署並調用對應的函式，驗證層是否如預期運作。

# 使用 Lambda 內容物件擷取 Python 函數資訊
<a name="python-context"></a>

當 Lambda 執行您的函數時，它會將內容物件傳遞至[處理常式](python-handler.md)。此物件提供的方法和各項屬性提供了有關調用、函式以及執行環境的資訊。如需如何將內容物件傳遞至函數處理常式的詳細資訊，請參閱[以 Python 定義 Lambda 函數處理常式](python-handler.md)。

**內容方法**
+ `get_remaining_time_in_millis` - 傳回執行逾時前剩餘的毫秒數。

**內容屬性**
+ `function_name` – Lambda 函數的名稱。
+ `function_version` – 函數的[版本](configuration-versions.md)。
+ `invoked_function_arn` - 用於叫用此函數的 Amazon Resource Name (ARN)。指出調用者是否指定版本號或別名。
+ `memory_limit_in_mb` - 分配給函數的記憶體數量。
+ `aws_request_id` - 調用請求的識別符。
+ `log_group_name` - 函數的日誌群組。
+ `log_stream_name` - 函數執行個體的記錄串流。
+ `identity` - (行動應用程式) 已授權請求的 Amazon Cognito 身分的相關資訊。
  + `cognito_identity_id` - 已驗證的 Amazon Cognito 身分。
  + `cognito_identity_pool_id` - 授權調用的 Amazon Cognito 身分集區。
+ `client_context` - (行動應用程式) 用戶端應用程式提供給 Lambda 的用戶端內容。
  + `client.installation_id`
  + `client.app_title`
  + `client.app_version_name`
  + `client.app_version_code`
  + `client.app_package_name`
  + `custom` - 行動用戶端應用程式所設定的 `dict` 自訂值。
  + `env` - AWS 開發套件所提供的 `dict` 環境資訊。

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 X-Ray 開發套件用於 [在 中檢測 Python 程式碼 AWS Lambda](python-tracing.md)，識別重要的程式碼路徑，追蹤它們的效能，並且擷取要進行分析的資料。

# 記錄和監控 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` 方法。下列範例會記錄 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>

如需更詳細的日誌，請使用標準程式庫中的 [logging](https://docs.python.org/3/library/logging.html) 模組，或任何寫入 `stdout` 或 `stderr` 的第三方記錄程式庫。

對於支援的 Python 執行期，您可以選擇是以純文字還是 JSON 擷取使用標準 `logging` 模組建立的日誌。如需詳細資訊，請參閱 [搭配 Python 使用 Lambda 進階日誌控制項](#python-logging-advanced)。

目前，所有 Python 執行期的預設日誌格式都是純文字。下列範例顯示如何在 CloudWatch Logs 日誌中以純文字擷取使用標準`logging` 模組建立的日誌輸出。

```
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 日誌物件都包含至少四個鍵值對，其中包含下列索引鍵：
+ `"timestamp"` - 產生日誌訊息的時間
+ `"level"` - 指派給訊息的日誌層級
+ `"message"` - 日誌訊息的內容
+ `"requestId"` - 進行調用的唯一請求 ID。

Python `logging` 程式庫還可以新增額外的鍵值對 (如 `"logger"`) 到這個 JSON 物件。

以下各章節中的範例顯示當您將函數的日誌格式設定為 JSON 時，如何在 CloudWatch Logs 日誌中擷取使用 Python `logging` 程式庫產生的記錄輸出。

請注意，如果您使用 `print` 方法產生基本的日誌輸出，如 [列印至日誌](#python-logging-output) 中所描述，即使您將函數的日誌格式設定為 JSON，Lambda 仍會以純文字擷取這些輸出。

#### 使用 Python 記錄程式庫進行標準 JSON 日誌輸出
<a name="python-logging-standard"></a>

下列範例程式碼片段和日誌輸出顯示當函數的日誌格式設為 JSON 時，如何在 CloudWatch Logs 中擷取使用 Python `logging` 程式庫產生的標準日誌輸出。

**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 等其他日誌程式庫 AWS Lambda來產生 JSON 結構化日誌，則不需要進行任何變更。 AWS Lambda 不會對已編碼 JSON 的任何日誌進行雙重編碼。即使您將函數設定為使用 JSON 日誌格式，您的記錄輸出也會以您定義的 JSON 結構顯示於 CloudWatch 中。

下列範例顯示如何在 CloudWatch Logs 中擷取使用適用於 AWS Lambda 套件的 Powertools 產生的日誌輸出。無論函數的日誌組態設定為 JSON 還是 TEXT，此日誌輸出的格式都相同。如需使用 Powertools 的詳細資訊 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 格式的日誌。您可以透過兩種方式達成此操作：
+ 使用標準 Python `logging` 程式庫建立日誌輸出，並配置您的函數以使用 JSON 日誌格式。然後 AWS Lambda 使用 [搭配 Python 使用結構化的 JSON 日誌](#python-logging-JSON) 中描述的 JSON 物件中的「層級」索引鍵值組篩選日誌輸出。若要瞭解如何設定函數的日誌格式，請參閱 [設定 Lambda 函數的進階日誌記錄控制項](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)。
+ 使用其他日誌程式庫或方法，在您的程式碼中建立 JSON 結構化日誌，其中包含定義日誌輸出層級的「層級」索引鍵值組。例如，您可以使用 Powertools for AWS Lambda 從程式碼產生 JSON 結構化日誌輸出。

  您也可以使用列印陳述式輸出包含日誌層級識別碼的 JSON 物件。下列列印陳述式會產生 JSON 格式的輸出，其中日誌層級設定為 INFO。如果您函數的日誌層級設定為 INFO、DEBUG 或 TRACE，則 AWS Lambda 會將 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 主控台來檢視日誌輸出。

如果可以從內嵌**程式碼**編輯器測試您的程式碼，您會在**執行結果**中找到日誌。使用主控台測試功能以調用函數時，您會在**詳細資訊**區段找到**日誌輸出**。

## 在 CloudWatch 主控台中檢視日誌
<a name="python-logging-cwconsole"></a>

您可以使用 Amazon CloudWatch 主控台來檢視所有 Lambda 函數調用的日誌。

**若要在 CloudWatch 主控台上檢視日誌**

1. 在 CloudWatch 主控台上開啟[日誌群組頁面](https://console.aws.amazon.com/cloudwatch/home?#logs:)。

1. 選擇您的函數的日誌群組 (**/aws/lambda/*your-function-name***)。

1. 選擇日誌串流

每個日誌串流都會對應至[函式的執行個體](lambda-runtime-environment.md)。當您更新 Lambda 函數時，以及建立其他執行個體來處理並行調用時，就會顯示日誌串流。若要尋找特定調用的日誌，建議您使用 檢測函數 AWS X-Ray。X-Ray 會在追蹤內記錄有關請求和日誌串流的詳細資訊。

## 使用 檢視日誌 AWS CLI
<a name="python-logging-cli"></a>

 AWS CLI 是一種開放原始碼工具，可讓您使用命令列 Shell 中的 命令與 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**  
下列範例顯示如何從名稱為 `my-function` 的函數的 `LogResult` 欄位來擷取*日誌 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
```
如果您使用的是第 2 AWS CLI 版，則需要 **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 和 [Ubuntu on Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10) 上使用。macOS 使用者可能需要使用 `base64 -D`。

**Example get-logs.sh 指令碼**  
在相同的命令提示中，使用下列指令碼下載最後五個日誌事件。該指令碼使用 `sed` 以從輸出檔案移除引述，並休眠 15 秒以使日誌可供使用。輸出包括來自 Lambda 的回應以及來自 `get-log-events` 命令的輸出。  
複製下列程式碼範例的內容，並將您的 Lambda 專案目錄儲存為 `get-logs.sh`。  
如果您使用的是第 2 AWS CLI 版，則需要 **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 擷取最後五個記錄事件**  
在相同的命令提示中，執行下列指令碼以取得最後五個日誌事件。  

```
./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/) 是一種開發人員工具組，可實作 Serverless 最佳實務並提高開發人員速度。[Logger 公用程式](https://docs.aws.amazon.com/powertools/python/latest/core/logger/)提供 Lambda 優化記錄器，其中包含有關所有函數之函數內容的其他資訊，輸出結構為 JSON。使用此公用程式執行下列操作：
+ 從 Lambda 內容、冷啟動和 JSON 形式的結構記錄輸出中擷取關鍵欄位
+ 在收到指示時記錄 Lambda 調用事件 (預設為停用)
+ 透過日誌採樣僅列印調用百分比的所有日誌 (預設為停用)
+ 在任何時間點將其他金鑰附加至結構化日誌
+ 使用自訂日誌格式化程式 (自帶格式化程式)，以與組織的日誌記錄 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 函數。當您將 GET 請求傳送至 API Gateway 端點時，Lambda 函數會調用、使用內嵌指標格式將日誌和指標傳送至 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 may not have authorization defined, Is this okay?**，確保輸入 `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 日誌](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>

請依照下列步驟，使用 下載、建置和部署範例 Hello World Python 應用程式，其中包含[適用於 AWS Lambda (Python) 模組的整合式 Powertools](https://docs.aws.amazon.com/powertools/python/latest/) AWS CDK。此應用程式實作了基本 API 後端，並使用 Powertools 發送日誌、指標和追蹤。其包含 Amazon API Gateway 端點和 Lambda 函數。當您將 GET 請求傳送至 API Gateway 端點時，Lambda 函數會調用、使用內嵌指標格式將日誌和指標傳送至 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\$1world\$1stack.py** 的檔案。

   ```
   cd ..
   cd hello_world
   ```

1. 開啟 **hello\$1world\$1stack.py**，並將下列程式碼新增至檔案。其中包含可建立 Lambda 函數、設定 Powertools 的環境變數並將日誌保留設定為一週的 [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 日誌](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/zh_tw/lambda/latest/dg/images/test-type-illustration2.png) 

 若為無伺服器測試，您仍需要寫入*單元*、*整合*及*端對端*測試。
+ **單元測試**：針對一組隔離的程式碼區塊進行的測試。例如，驗證商業邏輯以計算指定的特定項目與目的地的運費。
+ **整合測試**：涉及到兩個以上元件或服務進行互動的測試 (通常在雲端環境)。例如，驗證函數是否有處理佇列中的事件。
+ **端對端測試**：驗證整個應用程式行為的測試。例如，確保基礎設施的設定正確無誤，以及事件如預期在服務之間流動，以記錄客戶的訂單。

## 測試無伺服器應用程式
<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) 和 [AWS CDK 監看模式](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 和 Mock AWS Services 對 Lambda 進行單元測試](https://aws.amazon.com/blogs/devops/unit-testing-aws-lambda-with-python-and-mock-aws-services/)。

 若要降低與雲端部署反覆運算相關的延遲，請參閱 [AWS Serverless Application Model (AWS SAM) Accelerate](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)程式碼儲存庫。

# 在 中檢測 Python 程式碼 AWS Lambda
<a name="python-tracing"></a>

Lambda 與 整合 AWS X-Ray ，以協助您追蹤、偵錯和最佳化 Lambda 應用程式。您可以使用 X-Ray 來追蹤請求，因為它會周遊您應用程式中的資源，其中可能包含 Lambda 函數和其他 AWS 服務。

若要將追蹤資料傳送至 X-Ray，您可以使用以下三個 SDK 庫之一：
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel) – OpenTelemetry (OTel) SDK 的安全、生產就緒、 AWS支援的分發。
+ [適用於 Python 的 AWS X-Ray SDK](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/) – 開發人員工具組，用於實作 Serverless 最佳實務並提高開發人員速度。

每個 SDK 均提供將遙測資料傳送至 X-Ray 服務的方法。然後，您可以使用 X-Ray 來檢視、篩選應用程式的效能指標並獲得洞察，從而識別問題和進行最佳化的機會。

**重要**  
X-Ray 和 Powertools AWS Lambda SDKs是 提供的緊密整合檢測解決方案的一部分 AWS。ADOT Lambda Layers 是用於追蹤檢測之業界通用標準的一部分，這類檢測一般會收集更多資料，但可能不適用於所有使用案例。您可以使用任一解決方案在 X-Ray 中實作端對端追蹤。若要深入了解如何在兩者之間做選擇，請參閱[在 AWS Distro for OpenTelemetry 和 X-Ray SDK 之間進行選擇](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing)。

**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>

請依照下列步驟，使用 下載、建置和部署範例 Hello World Python 應用程式，其中包含[適用於 AWS Lambda (Python) 模組的整合式 Powertools](https://docs.powertools.aws.dev/lambda-python) AWS SAM。此應用程式實作了基本 API 後端，並使用 Powertools 發送日誌、指標和追蹤。其包含 Amazon API Gateway 端點和 Lambda 函數。當您將 GET 請求傳送至 API Gateway 端點時，Lambda 函數會調用、使用內嵌指標格式將日誌和指標傳送至 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 may not have authorization defined, Is this okay?**，確保輸入 `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 追蹤](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 次請求和 5% 的額外請求。不能針對函數設定 X-Ray 取樣率。

## 使用 Powertools for AWS Lambda (Python) 和 AWS CDK 進行追蹤
<a name="python-logging-cdk"></a>

請依照下列步驟，使用 下載、建置和部署範例 Hello World Python 應用程式，其中包含[適用於 AWS Lambda (Python) 模組的整合式 Powertools](https://docs.powertools.aws.dev/lambda-python) AWS CDK。此應用程式實作了基本 API 後端，並使用 Powertools 發送日誌、指標和追蹤。其包含 Amazon API Gateway 端點和 Lambda 函數。當您將 GET 請求傳送至 API Gateway 端點時，Lambda 函數會調用、使用內嵌指標格式將日誌和指標傳送至 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\$1world\$1stack.py** 的檔案。

   ```
   cd ..
   cd hello_world
   ```

1. 開啟 **hello\$1world\$1stack.py**，並將下列程式碼新增至檔案。其中包含可建立 Lambda 函數、設定 Powertools 的環境變數並將日誌保留設定為一週的 [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 追蹤](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 提供全受管 Lambda [層](chapter-layers.md)，包含使用 OTel SDK 收集遙測資料所需的一切內容。透過取用此層，您可以檢測 Lambda 函數，而無需修改任何函數程式碼。您還可以將層設定為對 OTel 進行自訂初始化。如需詳細資訊，請參閱 ADOT 文件中的[針對 Lambda 上的 ADOT 收集器進行自訂組態設定](https://aws-otel.github.io/docs/getting-started/lambda#custom-configuration-for-the-adot-collector-on-lambda)。

對於 Python 執行時間，您可以新增**適用於 ADOT Python 的AWS 受管 Lambda 層**來自動檢測您的函數。此層同時適用於 arm64 和 x86\$164 架構。如需有關如何新增此層的詳細指示，請參閱 ADOT 文件中的[適用於 Python 的AWS Distro for OpenTelemetry Lambda 支援](https://aws-otel.github.io/docs/getting-started/lambda/lambda-python)。

## 使用 X-Ray SDK 來檢測 Python 功能
<a name="python-xray-sdk"></a>

若要記錄 Lambda 函數對應用程式中其他資源所進行之呼叫的詳細資料，您也可以使用 適用於 Python 的 AWS X-Ray 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
```

在函數程式碼中，您可以使用 `aws_xray_sdk.core`模組修補程式`boto3`庫，以檢測 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)顯示了有關應用程式及其所有元件的資訊。下列範例顯示了一個具有兩個函數的應用程式。主要函式會處理事件，有時會傳回錯誤。頂端的第二個函數會處理出現在第一個日誌群組中的錯誤，並使用 AWS SDK 呼叫 X-Ray、Amazon Simple Storage Service (Amazon S3) 和 Amazon CloudWatch Logs。

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


X-Ray 無法追蹤應用程式的所有請求。X-Ray 會套用取樣演算法以確保追蹤的效率，同時仍提供所有請求的代表範本。取樣率為每秒 1 次請求和 5% 的額外請求。不能針對函數設定 X-Ray 取樣率。

在 X-Ray 中，*追蹤*會記錄一或多個*服務*所處理之要求的相關資訊。Lambda 會在每個追蹤上記錄 2 個區段，這會在服務圖表上建立兩個節點。下圖反白顯示了這兩個節點：

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


左側第一個節點代表接收調用請求的 Lambda 服務。第二個節點代表您特定的 Lambda 函數。下列範例顯示了具有這 2 個區段的追蹤。兩者都被命名為 **my-function**，但其中之一的來源為 `AWS::Lambda`，而另一個的來源為 `AWS::Lambda::Function`。如果 `AWS::Lambda` 區段顯示錯誤，Lambda 服務就會出現問題。如果 `AWS::Lambda::Function` 區段顯示錯誤，表示您的函數出現了問題。

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


此範例會展開 `AWS::Lambda::Function` 區段以顯示其三個子區段：

**注意**  
AWS 目前正在對 Lambda 服務實作變更。由於這些變更，您可能會看到系統日誌訊息的結構和內容，與 AWS 帳戶中不同 Lambda 函數發出的追蹤區段之間存在細微差異。  
此處顯示的追蹤範例說明了舊式函數區段。下列段落說明了舊式和新式區段之間的差異。  
這些變化將在未來幾週內實作，除中國和 GovCloud 區域以外，所有 AWS 區域 中的所有函數都會轉換至使用新格式的日誌訊息和追蹤區段。

舊式函數區段包含下列子區段：
+ **初始化** - 表示載入函數和執行[初始化程式碼](foundation-progmodel.md)所花費的時間。只有函數的每個執行個體所處理的第一個事件會顯示此子區段。
+ **調用** – 表示執行處理常式程式碼所花費的時間。
+ **額外負荷** - 表示 Lambda 執行期為做好準備以處理下一個事件所花費的時間。

新式函數區段不包含 `Invocation` 子區段。相反地，客戶子區段會直接連接至函數區段。如需舊式和新式函數區段結構的詳細資訊，請參閱[了解 X-Ray 追蹤](services-xray.md#services-xray-traces)。

您也可以檢測 HTTP 用戶端、記錄 SQL 查詢，以及建立具有註釋和中繼資料的自訂子區段。如需詳細資訊，請參閱《*AWS X-Ray 開發人員指南*》中的 [適用於 Python 的 AWS X-Ray SDK](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 開發套件來檢測函數程式碼的 AWS SDK 用戶端，您的部署套件可能會變得相當大。為了避免每次更新函數程式碼時上傳執行時間相依性，請將 X-Ray SDK 封裝在一個 [Lambda 層](chapter-layers.md)中。

以下範例會顯示存放 適用於 Python 的 AWS X-Ray SDK的 `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) 範例應用程式。