Blog

Python und relative Importe in AWS Lambda-Funktionen

Joris Conijn

Joris Conijn

Aktualisiert Oktober 20, 2025
3 Minuten

Wenn Sie eine AWS Lambda-Funktion schreiben, ist es gut möglich, dass Sie an einen Punkt kommen, an dem die Datei zu groß wird. Was tun Sie dann? Sie erstellen eine zweite Datei und refaktorisieren Ihren Code, um einen relativen Import durchzuführen. Dann bleibt nur noch der Schritt, Ihren Code zu verteilen und auszuführen. Und dann schlägt es fehl... Waren Sie schon einmal hier? Dann habe ich vielleicht einen guten Rat für Sie.

Wenn Sie sich den PEP 8 -- Style Guide for Python Code ansehen. , werden Sie lesen, dass werden absolute Importe empfohlen. Aber explizite relative Importe sind eine akzeptable Alternative zu absoluten Importen . Das bedeutet, dass Sie absolute Importe bevorzugen sollten. Und nur relative Importe innerhalb eines Pakets verwenden.

Beispiel-Code

Lassen Sie uns eine Hallo-Welt-Lambdafunktion erstellen, um dies zu zeigen. Wir haben also den folgenden Code in einer Datei namens hello_world/app.py:

import json

def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({"message": "hello world"}),
    }

Der Einfachheit halber habe ich das AWS Serverless Application Model verwendet. Die Vorlagen enthalten die folgende Ressource:

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

Das Wichtigste ist die Definition von Handler. Der Wert app.lambda_handler bedeutet soviel wie:

Verwenden Sie die Datei app.py und rufen Sie die Methode lambda_handler auf.

Wir werden nun die Nutzlast in eine Datei namens hello_world/response.py verschieben:

def get_response() -> dict:
    return {"message": "hello world"}

Und aktualisieren Sie die hello_world/app.py:

import json
from .response import get_response

def lambda_handler(event, context):

    return {
        "statusCode": 200,
        "body": json.dumps(get_response()),
    }

Sie führen Ihren Test aus und er funktioniert, gut! Also stellen wir jetzt unseren Code bereit und hoffen, dass er auch funktioniert. Und er schlägt fehl...

[ERROR] Runtime.ImportModuleError: Unable to import module 'app': attempted relative import with no known parent package
Traceback (most recent call last):

Der Inhalt des Ordners hello_world landet in dem Ordner /var/task/. Und nicht der Ordner selbst. Es könnte also so aussehen, als befände sich der Code in einem Paket, aber von der Lambda-Laufzeit aus gesehen ist er es nicht.

Die Lösung

Sie können dieses Problem lösen, indem Sie ein Paket erstellen. Wie, werden Sie fragen? Erstellen Sie einen Ordner hello_world im Ordner hello_world. Verschieben Sie alle Dateien außer requirements.txt in den erstellten Ordner.

Beispiel für die Ordnerstruktur

Als nächstes müssen Sie die Handler in der Vorlage aktualisieren:

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: hello_world.app.lambda_handler
      Runtime: python3.9
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

Der Wert von Handler entspricht nun dem:

Im Paket hello_world verwenden Sie die Datei app.py und rufen die Methode lambda_handler auf.

Bei der Bereitstellung werden Sie nun feststellen, dass der relative Import funktioniert.

Fazit

Ich würde Ihnen immer empfehlen, Ihren Python-Code in einem Paket bereitzustellen. Es macht es einfacher, viele Dateien zu verwenden und Ihren Code besser zu organisieren. Außerdem können Sie so die Logik der Lambda-Aufrufe von Ihrer Geschäftslogik trennen. Das macht es einfacher zu testen und zu warten.

Bild von Gerd Altmann von Pixabay

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.