Blog

Relative Python-Importe in einer Dockerized-Lambda-Funktion

Joris Conijn

Aktualisiert Oktober 15, 2025
3 Minuten

Relative Python-Importe können für Lambda-Funktionen schwierig sein. Ich habe vor 3 Jahren einen Blog darüber geschrieben. Aber vor kurzem bin ich auf das gleiche Problem mit Dockerized Lambda-Funktionen gestoßen. Also dachte ich mir, es ist Zeit für einen neuen Blog!

Sie können den Schritten folgen oder sich das Ergebnis direkt auf GitHub ansehen.

Projekt einrichten

Stellen Sie sicher, dass Sie das AWS CDK cli installiert haben.

brew install aws-cdk

Initialisieren Sie das Projekt:

cdk init app --language=typescript

Lambda-Einrichtung

Zunächst müssen wir die Datei- und Ordnerstruktur erstellen:

mkdir -p lib/functions/hello-world/hello_world
touch lib/functions/hello-world/hello_world/__init__.py
touch lib/functions/hello-world/hello_world/business_logic.py
touch lib/functions/hello-world/requirements.txt
touch lib/functions/hello-world/Dockerfile

Nun müssen Sie das Dockerfile wie folgt füllen:

FROM public.ecr.aws/lambda/python:3.12
COPY requirements.txt .
COPY hello_world ${LAMBDA_TASK_ROOT}/hello_world
RUN pip install --no-cache-dir -r requirements.txt
CMD ["hello_world.handler"]

Wir verwenden ein Python-Basis-Image, das auf Python 3.12 basiert. Als nächstes kopieren wir die Datei und den Quellcode hinein. Wir installieren alle in der Datei requirements.txt aufgeführten Abhängigkeiten und stellen sicher, dass die Methode handler als CMD eingestellt ist.

Als nächstes müssen wir unsere Python-Dateien mit etwas Code füllen. In der Datei __init__.py können Sie den folgenden Inhalt platzieren:

from typing import Dict, Any
# Example of the relative import
from .business_logic import business_logic


def handler(event: Dict[str, Any], context: Any) -> Dict[str, str]:
    # User the method that is imported based on a relative path
    name = business_logic(event)

    return {
        "Name": name,
        "Message": f"Hello {name}!",
    }

__all__ = [
    "handler"
]

Danach müssen wir die Datei business_logic.py füllen:

from typing import Dict, Any


def business_logic(event: Dict[str, Any]) -> str:
    return event.get("name", "World")

HINWEIS: Der hier verwendete Code könnte mehrere relative Importe verwenden. Dies ist möglich, weil er sich in einem separaten Paket befindet. Dieses Beispiel zeigt nur ein Beispiel in der Datei . Sie können hier jedoch mehrere Dateien verwenden, um die Wartbarkeit Ihres Projekts zu verbessern.

Für dieses Beispiel benötige ich keine Abhängigkeiten, also können wir die Datei requirements.txt leer lassen. Ich habe sie in dieses Beispiel aufgenommen, um zu zeigen, wie Sie auch Abhängigkeiten einfügen können.

Erstellen Sie die Lambda-Funktion mit IaC

Unsere Ordner und Dateien sind vorhanden. Es ist nun an der Zeit, die Lambda-Funktion zum CDK-Konstrukt hinzuzufügen. Sie können sie einfach wie folgt hinzufügen:

    new lambda.Function(this, 'Function', {
      functionName: "hello-world",
      code: lambda.Code.fromAssetImage("lib/functions/hello-world", {
        platform: ecr_assets.Platform.LINUX_ARM64,
      }),
      runtime: lambda.Runtime.FROM_IMAGE,
      handler: lambda.Handler.FROM_IMAGE,
      architecture: lambda.Architecture.ARM_64,
      timeout: cdk.Duration.seconds(15),
      memorySize: 128,
    });

Damit dies funktioniert, benötigen Sie außerdem die folgenden Importe:

import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets';

Beachten Sie, dass wir darauf achten, dass das Code-Verzeichnis auf das Verzeichnis verweist, das die Dockerfile enthält, und dass wir die ARM-Plattform sowohl für den Code als auch für die Funktion selbst auswählen.

Die Lambda-Funktion lokal testen

Schnelles Feedback ist wichtig, daher kann es vorkommen, dass Sie den Container lokal ausführen müssen. Dazu müssen Sie zunächst den Container erstellen:

docker build --platform linux/arm64 
  -t hello-world:latest 
  -f ./lib/functions/hello-world/Dockerfile 
  ./lib/functions/hello-world

Beachten Sie, dass dieser Befehl vom Stammverzeichnis des Projekts aus ausgeführt werden kann. Als nächstes müssen wir sicherstellen, dass er ausgeführt wird, bevor wir ihn aufrufen können:

docker run --platform linux/arm64 -p 9000:8080 hello-world:latest

Danach können Sie die Funktion wie folgt aufrufen:

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

Fazit

Relative Importe können knifflig sein! Sie müssen Ihren Code in einem Paket unterbringen. So können Sie relative Importe innerhalb Ihres eigenen Pakets durchführen. Dies ermöglicht einen saubereren Code, da Sie die Verantwortlichkeiten in mehrere Dateien aufteilen können, was die Verwaltung und Pflege erleichtert.

Foto von Kaique Rocha

Verfasst von

Joris Conijn

Joris is the AWS Practise CTO of the Xebia Cloud service line and has been working with the AWS cloud since 2009 and focussing on building event-driven architectures. While working with the cloud from (almost) the start, he has seen most of the services being launched. Joris strongly believes in automation and infrastructure as code and is open to learning new things and experimenting with them because that is the way to learn and grow.

Contact

Let’s discuss how we can support your journey.