Lambda-Funktionshandler in Python definieren - AWS Lambda

Lambda-Funktionshandler in Python definieren

Der Lambda-Funktionshandler ist die Methode in Ihrem Funktionscode, die Ereignisse verarbeitet. Wenn Ihre Funktion aufgerufen wird, führt Lambda die Handler-Methode aus. Ihre Funktion wird so lange ausgeführt, bis der Handler eine Antwort zurückgibt, beendet wird oder ein Timeout auftritt.

Auf dieser Seite wird beschrieben, wie Sie mit Lambda-Funktionshandlern in Python arbeiten, einschließlich Namenskonventionen, gültigen Handler-Signaturen und Best Practices für Code. Diese Seite enthält auch ein Beispiel für eine Python-Lambda-Funktion, die Informationen über einen Auftrag aufnimmt, eine Textdatei als Quittung erstellt und diese Datei in einem Bucket von Amazon Simple Storage Service (Amazon S3) platziert.

Beispiel für Python-Lambda-Funktionscode

Das folgende Beispiel für einen Python-Lambda-Funktionscode nimmt Informationen über eine Bestellung auf, erstellt eine Textdateiquittung und platziert diese Datei in einem Amazon-S3-Bucket:

Beispiel Python-Lambda-Funktion
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

Diese -Datei enthält die folgenden Abschnitte des Codes:

  • import-Block: Verwenden Sie diesen Block, um Bibliotheken einzubinden, die Ihre Lambda-Funktion benötigt.

  • Globale Initialisierung von SDK-Client und Logger: Durch das Einfügen von Initialisierungscode außerhalb des Handlers wird die Wiederverwendung der Ausführungsumgebung genutzt, um die Leistung Ihrer Funktion zu verbessern. Weitere Informationen hierzu finden Sie unter Bewährte Codemethoden für Python-Lambda-Funktionen.

  • def upload_receipt_to_s3(bucket_name, key, receipt_content):: Dies ist eine Hilfsfunktion, die von der lambda_handler-Hauptfunktion aufgerufen wird.

  • def lambda_handler(event, context):: Dies ist die Haupthandler-Funktion für Ihren Code, die Ihre Hauptanwendungslogik enthält. Wenn Lambda Ihren Funktionshandler aufruft, übergibt die Lambda-Laufzeit zwei Argumente an die Funktion: das Ereignisobjekt, das Daten für die Verarbeitung durch Ihre Funktion enthält, und das Kontextobjekt, das Informationen über den Funktionsaufruf enthält.

Namenskonventionen für Handler

Der zum Zeitpunkt der Erstellung einer Lambda-Funktion definierte Funktionshandlername wird abgeleitet von:

  • dem Namen der Datei, in der sich die Lambda-Handler-Funktion befindet.

  • dem Namen der Python-Handler-Funktion.

Wenn die Datei im obigen Beispiel lambda_function.py heißt, wird der Handler als lambda_function.lambda_handler angegeben. Dies ist der Standard-Handlername für Funktionen, die Sie mit der Lambda-Konsole erstellen.

Wenn Sie eine Funktion in der Konsole mit einem anderen Dateinamen oder Funktionshandlernamen erstellen, müssen Sie den Standardhandlernamen bearbeiten.

So ändern Sie den Funktionshandlernamen (Konsole)
  1. Öffnen Sie die Seite Functions (Funktionen) der Lambda-Konsole und wählen Sie eine Funktion aus.

  2. Wählen Sie die Registerkarte Code (Code).

  3. Scrollen Sie nach unten zum Bereich Laufzeiteinstellungen und wählen Sie Bearbeiten.

  4. Geben Sie unter Handler den neuen Namen für Ihren Funktionshandler ein.

  5. Wählen Sie Speichern.

Verwenden des Lambda-Ereignisobjekts

Wenn Lambda Ihre Funktion aufruft, wird dem Funktionshandler ein Ereignisobjekt-Argument übergeben. JSON-Objekte sind das gängigste Ereignisformat für Lambda-Funktionen. Im Codebeispiel im vorherigen Abschnitt erwartet die Funktion eine Eingabe im folgenden Format:

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

Wenn Ihre Funktion von einem anderen AWS-Service aufgerufen wird, ist das Eingabeereignis ebenfalls ein JSON-Objekt. Das genaue Format des Ereignisobjekts hängt vom Service ab, der Ihre Funktion aufruft. Das Ereignisformat für einen bestimmten Service finden Sie auf der entsprechenden Seite im Kapitel „Lambda mit Ereignissen aus anderen AWS-Diensten aufrufen“.

Wenn das Eingabeereignis in Form eines JSON-Objekts vorliegt, konvertiert die Lambda-Laufzeit das Objekt in ein Python-Wörterbuch. Um Werte in der Eingabe-JSON Variablen in Ihrem Code zuzuweisen, verwenden Sie die Standardmethoden für Python-Wörterbücher, wie im Beispielcode dargestellt.

Sie können Daten auch als JSON-Array oder als einen der anderen gültigen JSON-Datentypen an Ihre Funktion übergeben. In der folgenden Tabelle ist definiert, wie die Python-Laufzeit diese JSON-Typen konvertiert.

JSON-Datentyp Python-Datentyp
object Wörterbuch (dict)
Array Liste (list)
Zahl Ganzzahl (int) oder Fließkommazahl (float)
Zeichenfolge Zeichenfolge (str)
Boolesch Boolesch (bool)
Null NoneType (NoneType)

Zugreifen auf und Verwenden des Lambda-Kontextobjekts

Das Lambda-Kontextobjekt enthält Informationen über den Funktionsaufruf und die Ausführungsumgebung. Lambda übergibt das Kontextobjekt automatisch an Ihre Funktion, wenn diese aufgerufen wird. Mit dem Kontextobjekt können Sie zu Überwachungszwecken Informationen über den Aufruf Ihrer Funktion ausgeben.

Das Kontextobjekt ist eine Python-Klasse, die im Schnittstellenclient der Lambda-Laufzeit definiert ist. Um den Wert einer der Eigenschaften des Kontextobjekts zurückzugeben, verwenden Sie die entsprechende Methode des Kontextobjekts. Im folgenden Codeausschnitt wird beispielsweise der Wert der aws_request_id-Eigenschaft (die Kennung für die Aufrufanforderung) einer Variablen namens request zugewiesen.

request = context.aws_request_id

Weitere Informationen zur Verwendung des Lambda-Kontextobjekts und eine vollständige Liste der verfügbaren Methoden und Eigenschaften finden Sie unter Verwenden des Lambda-Kontextobjekts zum Abrufen von Python-Funktionsinformationen.

Gültige Handler-Signaturen für Python-Handler

Wenn Sie Ihre Handler-Funktion in Python definieren, muss die Funktion zwei Argumente enthalten. Das erste dieser Argumente ist das Lambda-Ereignisobjekt und das zweite ist das Lambda-Kontextobjekt. Gemäß Konvention heißen diese Eingabeargumente in der Regel event und context, Sie können ihnen jedoch beliebige Namen geben. Wenn Sie Ihre Handler-Funktion mit einem einzigen Eingabeargument deklarieren, löst Lambda einen Fehler aus, wenn es versucht, Ihre Funktion auszuführen. Die gängigste Methode zum Deklarieren einer Handler-Funktion in Python ist wie folgt:

def lambda_handler(event, context):

Sie auch können Python-Typhinweise in Ihrer Funktionsdeklaration verwenden, wie im folgenden Beispiel gezeigt:

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

Um spezifische AWS-Typisierungen für Ereignisse zu verwenden, die von anderen AWS-Services generiert werden, sowie für das Kontextobjekt, fügen Sie das Paket aws-lambda-typing zum Bereitstellungspaket Ihrer Funktion hinzu. Sie können diese Bibliothek in Ihrer Entwicklungsumgebung installieren, indem Sie pip install aws-lambda-typing ausführen. Der folgende Codeausschnitt zeigt, wie Sie AWS-spezifische Typhinweise verwenden. In diesem Beispiel ist das erwartete Ereignis ein Amazon-S3-Ereignis.

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]:

Sie können den Python-Funktionstyp async nicht für Ihre Handler-Funktion verwenden.

Rückgabe eines Wertes

Optional kann ein Handler einen Wert zurückgeben, der JSON-serialisierbar sein muss. Zu den gängigen Rückgabetypen gehören dict, list, str, int, float und bool.

Was mit dem zurückgegebenen Wert passiert, hängt von der Aufrufart und dem Service ab, der die Funktion aufgerufen hat. Zum Beispiel:

  • Wenn Sie den Aufruftyp RequestResponse verwenden, um eine Lambda-Funktion synchron aufzurufen, gibt Lambda das Ergebnis des Python-Funktionsaufrufs an den Client zurück, der die Lambda-Funktion aufruft (in der HTTP-Antwort auf die Aufrufanforderung, serialisiert in JSON). Wenn eine AWS Lambda-Konsole zum Beispiel den Aufruftyp RequestResponse verwendet, zeigt die Konsole den zurückgegebenen Wert an, nachdem die Funktion auf der Konsole abgerufen wurde.

  • Wenn der Handler Objekte zurückgibt, die nicht von json.dumps serialisiert werden können, gibt die Laufzeit einen Fehler zurück.

  • Wenn der Handler None zurückgibt, wie es Python-Funktionen ohne eine return-Anweisung implizit tun, gibt die Laufzeit null zurück.

  • Wenn Sie den Aufruftyp Event (asynchroner Aufruf) verwenden, wird der Wert verworfen.

Im Beispielcode gibt der Handler das folgende Python-Wörterbuch zurück:

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

Die Lambda-Laufzeit serialisiert dieses Wörterbuch und gibt es als JSON-Zeichenfolge an den Client zurück, der die Funktion aufgerufen hat.

Anmerkung

In Python 3.9 und späteren Versionen schließt Lambda die requestId des Aufrufs in die Fehlerantwort ein.

Verwenden Sie das AWS SDK für Python (Boto3) in Ihrem Handler

Oft verwenden Sie Lambda-Funktionen, um mit anderen AWS-Services und Ressourcen zu interagieren. Die einfachste Art, eine Schnittstelle zu diesen Ressourcen herzustellen, ist die Verwendung von AWS SDK für Python (Boto3). Alle unterstützten Lambda-Python-Laufzeiten enthalten eine Version des SDK für Python. Wir empfehlen jedoch dringend, das SDK in das Bereitstellungspaket Ihrer Funktion aufzunehmen, wenn Ihr Code es verwenden muss. Durch das Einfügen des SDK in Ihr Bereitstellungspaket erhalten Sie die volle Kontrolle über Ihre Abhängigkeiten und verringern das Risiko von Versionskonflikten mit anderen Bibliotheken. Weitere Informationen dazu finden Sie unter Laufzeitabhängigkeiten in Python und Abwärtskompatibilität.

Um das SDK für Python in Ihrer Lambda-Funktion zu verwenden, fügen Sie die folgende Anweisung zum Importblock am Anfang Ihres Funktionscodes hinzu:

import boto3

Verwenden den pip install-Befehl, um Bibliothek boto3 dem Bereitstellungspaket Ihrer Funktion hinzuzufügen. Ausführliche Anweisungen zum Hinzufügen von Abhängigkeiten zu einem ZIP-Bereitstellungspaket finden Sie unter ZIP-Bereitstellungspakets mit Abhängigkeiten erstellen. Weitere Informationen zum Hinzufügen von Abhängigkeiten zu Lambda-Funktionen, die als Container-Images bereitgestellt werden, finden Sie unter Erstellen eines Images aus einem Base Image oder Erstellen eines Images aus einem alternativen Basis-Image.

Wenn Sie boto3 in Ihrem Code verwenden, müssen Sie keine Anmeldeinformationen angeben, um einen Client zu initialisieren. Im Beispielcode verwenden wir beispielsweise die folgende Codezeile, um einen Amazon-S3-Client zu initialisieren:

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

Mit Python erstellt Lambda automatisch Umgebungsvariablen mit Anmeldeinformationen. Das boto3 SDK überprüft die Umgebungsvariablen Ihrer Funktion bei der Initialisierung auf diese Anmeldeinformationen.

Zugriff auf Umgebungsvariablen

In Ihrem Handler-Code können Sie mithilfe der os.environ.get-Methode auf Umgebungsvariablen verweisen. Im Beispielcode verweisen wir mit der folgenden Codezeile auf die definierte RECEIPT_BUCKET-Umgebungsvariable:

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

Vergessen Sie nicht, am Anfang Ihres Codes eine import os-Anweisung in den Importblock aufzunehmen.

Bewährte Codemethoden für Python-Lambda-Funktionen

Halten Sie sich an die Richtlinien in der folgenden Liste, um beim Erstellen Ihrer Lambda-Funktionen die besten Codierungspraktiken anzuwenden:

  • Trennen Sie den Lambda-Handler von Ihrer Core-Logik. Auf diese Weise können Sie eine Funktion zur besseren Prüfbarkeit von Einheiten schaffen. In Python kann dies beispielsweise wie folgt aussehen:

    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
  • Kontrollieren Sie die Abhängigkeiten im Bereitstellungspaket Ihrer Funktion. Die AWS Lambda-Ausführungsumgebung enthält eine Reihe von Bibliotheken. Für die Laufzeiten Node.js und Python gehören dazu die AWS-SDKs. Um die neuesten Funktionen und Sicherheitsupdates zu aktivieren, wird Lambda diese Bibliotheken regelmäßig aktualisieren. Diese Updates können das Verhalten Ihrer Lambda-Funktion geringfügig verändern. Um die Abhängigkeiten, die Ihre Funktion verwendet, vollständig zu kontrollieren, empfehlen wir, alle Abhängigkeiten mit Ihrem Bereitstellungspaket zu bündeln.

  • Minimieren Sie die Komplexität Ihrer Abhängigkeiten. Ziehen Sie einfachere Frameworks vor, die sich schnell beim Start der Ausführungsumgebung laden lassen.

  • Minimieren Sie die Größe Ihres Bereitstellungspakets auf die für die Laufzeit erforderliche Größe. Dadurch verkürzt sich die Zeit, die für das Herunterladen und Entpacken Ihres Bereitstellungspakets vor dem Aufruf benötigt wird.

Nutzen Sie die Wiederverwendung der Ausführungsumgebung zur Verbesserung Ihrer Funktion. Initialisieren Sie SDK-Clients und Datenbankverbindungen außerhalb des Funktions-Handlers und speichern Sie statische Komponenten lokal im /tmp-Verzeichnis. Nachfolgende Aufrufe, die von derselben Instance Ihrer Funktion verarbeitet werden, können diese Ressourcen wiederverwenden. Dies spart Kosten durch Reduzierung der Funktionslaufzeit.

Um potenzielle Datenlecks über Aufrufe hinweg zu vermeiden, verwenden Sie die Ausführungsumgebung nicht, um Benutzerdaten, Ereignisse oder andere Informationen mit Sicherheitsauswirkungen zu speichern. Wenn Ihre Funktion auf einem veränderbaren Zustand beruht, der nicht im Speicher innerhalb des Handlers gespeichert werden kann, sollten Sie für jeden Benutzer eine separate Funktion oder separate Versionen einer Funktion erstellen.

Verwenden Sie eine Keep-Alive-Direktive, um dauerhafte Verbindungen zu pflegen. Lambda bereinigt Leerlaufverbindungen im Laufe der Zeit. Der Versuch, eine Leerlaufverbindung beim Aufruf einer Funktion wiederzuverwenden, führt zu einem Verbindungsfehler. Um Ihre persistente Verbindung aufrechtzuerhalten, verwenden Sie die Keep-Alive-Direktive, die Ihrer Laufzeit zugeordnet ist. Ein Beispiel finden Sie unter Wiederverwenden von Verbindungen mit Keep-Alive in Node.js.

Verwenden Sie Umgebungsvariablen um Betriebsparameter an Ihre Funktion zu übergeben. Wenn Sie z. B. Daten in einen Amazon-S3-Bucket schreiben, anstatt den Bucket-Namen, in den Sie schreiben, hartzucodieren, konfigurieren Sie den Bucket-Namen als Umgebungsvariable.

Vermeiden Sie rekursive Aufrufe in Ihrer Lambda-Funktion, bei denen die Funktion sich selbst aufruft oder einen Prozess initiiert, der die Funktion erneut aufrufen kann. Dies kann zu unvorhergesehenen Mengen an Funktionsaufrufen führen und höhere Kosten zur Folge haben. Wenn Sie eine unbeabsichtigte Menge von Aufrufen feststellen, legen Sie die reservierte gleichzeitige Ausführung der Funktion auf 0 fest, um sofort alle Aufrufe der Funktion zu drosseln, während Sie den Code aktualisieren.

Verwenden Sie keine nicht dokumentierten, nicht öffentlichen APIs in Ihrem Lambda-Funktionscode. Für AWS Lambda-verwaltete Laufzeiten wendet Lambda regelmäßig Sicherheits- und Funktionsupdates auf Lambdas interne APIs an. Diese internen API-Updates können abwärtskompatibel sein, was zu unbeabsichtigten Konsequenzen wie Aufruffehlern führt, wenn Ihre Funktion von diesen nicht öffentlichen APIs abhängig ist. Eine Liste öffentlich zugänglicher APIs finden Sie in der API-Referenz.

Schreiben Sie idempotenten Code. Das Schreiben idempotenter Code für Ihre Funktionen stellt sicher, dass doppelte Ereignisse auf die gleiche Weise behandelt werden. Ihr Code sollte Ereignisse ordnungsgemäß validieren und doppelte Ereignisse ordnungsgemäß behandeln. Weitere Informationen finden Sie unter Wie mache ich meine Lambda-Funktion idempotent?.