本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
以 Python 定義 Lambda 函數處理常式
Lambda 函數處理常式是您的函數程式碼中處理事件的方法。當有人呼叫您的函數時,Lambda 會執行處理常式方法。函數會執行,直到處理常式傳回回應、結束或逾時為止。
此頁面說明如何在 Python 中使用 Lambda 函數處理常式,包括命名慣例、有效的處理常式簽章和程式碼最佳實務。此頁面也包含 Python Lambda 函數的範例,該函數會取得訂單的相關資訊、產生文字檔案接收,並將此檔案放入 Amazon Simple Storage Service (Amazon S3) 儲存貯體。
主題
Python Lambda 函數程式碼範例
下列範例 Python Lambda 函數程式碼會取得訂單的相關資訊、產生文字檔案接收,並將此檔案放入 Amazon S3 儲存貯體:
範例 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 用戶端和記錄器的全域初始化:包含處理常式以外的初始化程式碼,會利用重複使用的執行環境來改善函數的效能。如需進一步了解,請參閱Python Lambda 函數的程式碼最佳實務。
-
def upload_receipt_to_s3(bucket_name, key, receipt_content):
這是主要函數呼叫的協助程式lambda_handler
函數。 -
def lambda_handler(event, context):
這是程式碼的主要處理常式函數,其中包含您的主要應用程式邏輯。當 Lambda 調用函數處理常式時,Lambda 執行時間會將兩個引數傳遞至函數、包含函數要處理之資料的事件物件,以及包含函數調用相關資訊的內容物件。
處理常式命名慣例
在您建立 Lambda 函數時定義的函數處理常式名稱衍生自:
-
Lambda 處理常式函數所在的檔案名稱。
-
Python 處理常式函數的名稱。
在上述範例中,如果檔案名為 lambda_function.py
,則處理常式會指定為 lambda_function.lambda_handler
。這是您使用 Lambda 主控台建立之函數的預設處理常式名稱。
如果要在主控台中使用不同檔案名稱或函數處理常式名稱建立函數,您必須編輯預設處理常式名稱。
變更函數處理常式名稱的方式 (主控台)
-
開啟 Lambda 主控台的函數
頁面,然後選擇您的函數。 -
選擇 程式碼 索引標籤。
-
向下捲動至執行時間設定窗格,並選擇編輯。
-
在處理常式中,輸入函數處理常式的新名稱。
-
選擇 Save (儲存)。
使用 Lambda 事件物件
當 Lambda 調用您的函數時,它會將事件物件引數傳遞給函數處理常式。JSON 物件是 Lambda 函數最常見的事件格式。在上一節的程式碼範例中,函數預期輸入格式如下:
{ "Order_id": "12345", "Amount": 199.99, "Item": "Wireless Headphones" }
如果您的函數被另一個函數叫用 AWS 服務,則輸入事件也是 JSON 物件。事件物件的確切格式取決於叫用函數的服務。若要查看特定服務的事件格式,請參閱 使用來自其他服務的事件叫用 Lambda AWS章節中的適當頁面。
如果輸入事件是 JSON 物件的形式,Lambda 執行時間會將物件轉換為 Python 字典。若要將輸入 JSON 中的值指派給程式碼中的變數,請使用範例程式碼中所示的標準 Python 字典方法。
您也可以將資料以 JSON 陣列的形式,或做為任何其他有效的 JSON 資料類型傳遞到您的函數。下表定義 Python 執行期如何轉換這些 JSON 類型。
JSON 資料類型 | Python 資料類型 |
---|---|
object | 字典 (dict ) |
陣列 | 清單 (list ) |
number | 整數 (int ) 或浮點數 (float ) |
string | 字串 (str ) |
Boolean | 布林值 (bool ) |
null | NoneType (NoneType ) |
存取和使用 Lambda 內容物件
Lambda 內容物件包含函數調用和執行環境的相關資訊。Lambda 調用時會自動將內容物件傳遞至您的函數。您可以使用內容物件,基於監控目的,輸出函數調用的資訊。
內容物件是在 Lambda 執行期介面用戶端aws_request_id
屬性的值 (呼叫請求的識別符) 指派給名為 的變數request
。
request = context.aws_request_id
若要進一步了解如何使用 Lambda 內容物件,以及查看可用方法和屬性的完整清單,請參閱使用 Lambda 內容物件擷取 Python 函數資訊。
Python 處理常式的有效處理常式簽章
在 Python 中定義處理常式函數時,該函數必須採用兩個引數。這些引數中的第一個是 Lambda 事件物件,第二個是 Lambda 內容物件。根據慣例,這些輸入引數通常命名為 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
套件新增至函數的部署套件。您可以執行 ,在開發環境中安裝此程式庫
。下列程式碼片段說明如何使用 AWS特定的類型提示。在此範例中,預期事件是 Amazon S3 事件。pip install aws-lambda-typing
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
函數類型用於處理常式函數。
傳回值
或者,處理常式可以傳回值,該值必須是 JSON 可序列化的。常見的傳回類型包括 dict
、list
、str
、float
、 int
和 bool
。
-
如果您使用
RequestResponse
叫用類型同步叫用 Lambda 函數,Lambda 會將 Python 函數呼叫的結果傳回給叫用 Lambda 函數的用戶端 (在叫用請求的 HTTP 回應中,序列化為 JSON)。例如, AWS Lambda 主控台使用RequestResponse
調用類型。因此,當您在主控台上調用函數時,主控台即會顯示傳回值。 -
如果處理常式傳回
json.dumps
無法序列化的物件,則執行時間會傳回錯誤。 -
如果處理常式傳回
None
(如沒有return
陳述式的 Python 函數隱含作業),則執行時間會傳回null
。 -
如果使用
Event
調用類型 (非同步調用),便會捨棄該值。
在範例程式碼中,處理常式會傳回下列 Python 字典:
{ "statusCode": 200, "message": "Receipt processed successfully" }
Lambda 執行時間會序列化此字典,並將其傳回給叫用函數的用戶端,做為 JSON 字串。
注意
在 Python 3.9 及更高版本中,Lambda 會在錯誤回應中包含調用的請求 ID。
在處理常式 AWS SDK for Python (Boto3) 中使用
通常,您將使用 Lambda 函數與其他 AWS 服務 和資源互動。與這些資源互動的最簡單方法是使用 AWS SDK for Python (Boto3)。所有支援的 Lambda Python 執行時間都包含適用於 Python 的 SDK 版本。不過,如果您的程式碼需要使用 SDK,我們強烈建議您在函數的部署套件中包含 SDK。在您的部署套件中包含開發套件可讓您完全控制相依性,並降低與其他程式庫發生版本不一致問題的風險。如需進一步了解,請參閱 Python 中的執行期相依項 和 回溯相容性。
若要在 Lambda 函數中使用適用於 Python 的 SDK,請在函數程式碼的開頭將下列陳述式新增至匯入區塊:
import boto3
使用 pip install
命令將boto3
程式庫新增至函數的部署套件。如需如何將相依性新增至 .zip 部署套件的詳細說明,請參閱 建立含相依項的 .zip 部署套件。若要進一步了解如何將相依性新增至部署為容器映像的 Lambda 函數,請參閱 從基礎映像建立映像或 使用替代基礎映像建立映像。
在程式碼boto3
中使用 時,您不需要提供任何登入資料即可初始化用戶端。例如,在範例程式碼中,我們使用下列程式碼行來初始化 Amazon S3 用戶端:
# Initialize the S3 client outside of the handler s3_client = boto3.client('s3')
使用 Python,Lambda 會自動使用登入資料建立環境變數。軟體boto3
開發套件會在初始化期間檢查函數的環境變數,以找出這些登入資料。
存取環境變數
在處理常式程式碼中,您可以使用 os.environ.get
方法參考環境變數。在範例程式碼中,我們使用下列程式碼行來參考定義的RECEIPT_BUCKET
環境變數:
# Access environment variables bucket_name = os.environ.get('RECEIPT_BUCKET')
別忘了在程式碼開頭的匯入區塊中包含 import os
陳述式。
Python Lambda 函數的程式碼最佳實務
請遵循下列清單中的準則,在建置 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 SDKs。若要啟用最新的一組功能與安全更新,Lambda 會定期更新這些程式庫。這些更新可能會為您的 Lambda 函數行為帶來細微的變更。若要完全掌控您函式所使用的相依性,請利用部署套件封裝您的所有相依性。
-
最小化依存項目的複雜性。偏好更簡易的框架,其可快速在執行環境啟動時載入。
-
將部署套件最小化至執行時間所必要的套件大小。這能減少您的部署套件被下載與呼叫前解壓縮的時間。
-
請利用執行環境重新使用來改看函式的效能。在函式處理常式之外初始化 SDK 用戶端和資料庫連線,並在本機快取
/tmp
目錄中的靜態資產。由您函式的相同執行個體處理的後續叫用可以重複使用這些資源。這可藉由減少函數執行時間來節省成本。若要避免叫用間洩漏潛在資料,請不要使用執行環境來儲存使用者資料、事件,或其他牽涉安全性的資訊。如果您的函式依賴無法存放在處理常式內記憶體中的可變狀態,請考慮為每個使用者建立個別函式或個別函式版本。
-
使用 Keep-Alive 指令維持持續連線的狀態。Lambda 會隨著時間的推移清除閒置連線。叫用函數時嘗試重複使用閒置連線將導致連線錯誤。若要維護持續連線,請使用與執行階段相關聯的 keep-alive (保持啟用) 指令。如需範例,請參閱在 Node.js 中重複使用 Keep-Alive 的連線。
-
使用環境變數將操作參數傳遞給您的函數。例如,如果您正在寫入到 Amazon S3 儲存貯體,而非對您正在寫入的儲存貯體名稱進行硬式編碼,請將儲存貯體名稱設定為環境變數。
-
避免在 Lambda 函數中使用遞迴調用,其中函數會調用自己或啟動可能再次調用函數的程序。這會導致意外的函式呼叫量與升高的成本。若您看到意外的調用數量,當更新程式碼時,請立刻將函數的預留並行設為
0
,以調節對函數的所有調用。 -
請勿在您的 Lambda 函數程式碼中使用未記錄的非公有 API。對於 AWS Lambda 受管執行期,Lambda 會定期將安全性和功能更新套用至 Lambda 的內部 APIs。這些內部 API 更新可能是向後不相容的,這會導致意外結果,例如若您的函數依賴於這些非公有 API,則叫用失敗。請參閱 API 參考查看公開可用 API 的清單。
-
撰寫等冪程式碼。為函數撰寫等冪程式碼可確保採用相同方式來處理重複事件。程式碼應正確驗證事件並正常處理重複的事件。如需詳細資訊,請參閱 How do I make my Lambda function idempotent?
(如何讓 Lambda 函數等冪?)。