AWS Lambda-Importmodulfehler in Python

91

Ich erstelle ein AWS Lambda Python-Bereitstellungspaket. Ich verwende eine externe Abhängigkeitsanforderung. Ich habe die externe Abhängigkeit mithilfe der AWS-Dokumentation http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html installiert . Unten ist mein Python-Code.

import requests

print('Loading function')

s3 = boto3.client('s3')


def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        s3.download_file(bucket,key, '/tmp/data.txt')
        lines = [line.rstrip('\n') for line in open('/tmp/data.txt')]
        for line in lines:
            col=line.split(',')
            print(col[5],col[6])
        print("CONTENT TYPE: " + response['ContentType'])
        return response['ContentType']
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e

Erstellt die Zip den Inhalt des Projektverzeichnisverzeichnisses und lädt es in das Lambda hoch (Zip den Verzeichnisinhalt, nicht das Verzeichnis). Wenn ich die Funktion ausführe, erhalte ich den unten genannten Fehler.

START RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058 Version: $LATEST
**Unable to import module 'lambda_function': No module named lambda_function**

END RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058
REPORT RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058  Duration: 19.63 ms  Billed Duration: 100 ms     Memory Size: 128 MB Max Memory Used: 9 MB

Bitte helfen Sie mir, den Fehler zu debuggen.

Nithin K Anil
quelle
Ist es Ihr vollständiger Code? Durch den Fehler scheint es irgendwo etwas zu wollen, import lambda_functiondas nicht gefunden wird. Vielleicht willst du from future import lambda_function? Oder installieren Sie einfach lambda_function in der cmd-Zeile.
Berci
@Berci Ich führe diesen Python-Code auf der AWS-Plattform aus. Ich kann pip nicht benutzen. irgendwo in meinem Code verwende ich lambda_function.
Wenn
Siehe den letzten Kommentar zu diesem Thread - trifft vielleicht auf Sie zu?
Kwinkunks
@ Kwinkunks Das habe ich versucht. Eigentlich zippe ich den Inhalt nicht das Verzeichnis !!
Nithin K Anil
2
Ich vermute, dass die Option "Handler" in Ihrer Funktion falsch ist. Überprüfen Sie, ob Ihr Dateiname "lambda_function.py" und die Handler-Methode "lambda_handler" lautet
Vor dem

Antworten:

108

Der Fehler war auf den Dateinamen der Lambda-Funktion zurückzuführen. Beim Erstellen der Lambda-Funktion wird nach dem Lambda-Funktionshandler gefragt. Sie müssen es als Python_File_Name.Method_Name benennen . In diesem Szenario habe ich es als lambda.lambda_handler bezeichnet (lambda.py ist der Dateiname).

Nachfolgend finden Sie den Schnappschuss. Geben Sie hier die Bildbeschreibung ein

Nithin K Anil
quelle
1
Mein Code ist nur in Lambda als Code - nicht als Datei.
Ben Wheeler
4
@ BenWheeler: Obwohl es sich um Inline-Code handelt, handelt es sich um eine Datei, die Sie tatsächlich schreiben. Sie können den Dateinamen und die gesamte Verzeichnisstruktur links im Fenster sehen.
Vineeth
Also hatte ich meinen Code als "lambda_function.py" bezeichnet. Sollte ich den Handler als Python_lambda_function.lambda_handler benennen?
RB17
@ RahulBanerjee Nein. Sie würden es als lambda_function.lambda_handler
Dinesh
84

Wenn Sie eine Zip-Datei hochladen. Stellen Sie sicher, dass Sie den Inhalt des Verzeichnisses und nicht das Verzeichnis selbst komprimieren.

2ank3th
quelle
2
Stellen Sie beim Zippen sicher, dass Sie auch das Flag -r verwenden!
Grant Robert Smith
@ 2ank3th du bist der Beste
Sethuraman Srinivasan
24

Eine weitere Ursache für dieses Problem sind die Berechtigungen für die komprimierte Datei. Es muss mindestens weltweit lesbar sein. (min chmod 444)

Ich habe Folgendes für die Python-Datei ausgeführt, bevor ich sie komprimiert habe, und sie hat einwandfrei funktioniert.

chmod u=rwx,go=r
Catalin Ciurea
quelle
4
Dies. Ich habe Pythons ZipFile verwendet, um die Lambda-Funktionen programmgesteuert in die ZIP-Datei zu packen. Standardmäßig reicht dies aus, 0600was, wie Sie bereits erwähnt haben, nicht ausreicht. Darüber hinaus liest der integrierte Lambda-Quellcode-Editor (auf der Amazon-Webseite) die Datei ohne Warnung vor Berechtigungsproblemen.
cjhanks
2
Zweite. Ich habe es zum Laufen
dokkaebi
15

Ich fand Nithins Antwort sehr hilfreich. Hier ist eine spezielle Anleitung:

Schlagen Sie diese Werte nach:

  1. Der Name der Funktion lambda_handler in Ihrem Python-Skript. Der in den AWS-Beispielen verwendete Name lautet "lambda_handler" und sieht aus wie "def lambda_handler (Ereignis, Kontext)". In diesem Fall lautet der Wert "lambda_handler".
  2. Suchen Sie im Lambda-Dashboard den Namen des Handlers im Textfeld "Handler" im Abschnitt "Konfiguration" des Lambda-Dashboards für die Funktion (siehe Nithins Screenshot). Mein Standardname war "lambda_function.lambda_handler".
  3. Der Name Ihres Python-Skripts. Nehmen wir an, es ist "cool.py"

Mit diesen Werten müssten Sie den Handler (siehe Screenshot) in "cool.lambda_handler" umbenennen. Dies ist eine Möglichkeit, die Fehlermeldung "Modul 'lambda_function' kann nicht importiert werden" zu entfernen. Wenn Sie den Handler in Ihrem Python-Skript in "sup" umbenennen möchten, müssen Sie den Handler im Lambda-Dashboard in "cool.sup" umbenennen.

user3303554
quelle
11

Beim Erstellen von Bereitstellungspaketen für AWS Lambda (für Python) gibt es nur so viele Fallstricke . Ich habe Stunden und Stunden mit Debugging-Sitzungen verbracht, bis ich eine Formel gefunden habe, die selten fehlschlägt.

Ich habe ein Skript erstellt, das den gesamten Prozess automatisiert und ihn daher weniger fehleranfällig macht. Ich habe auch ein Tutorial geschrieben, das erklärt, wie alles funktioniert. Vielleicht möchten Sie es ausprobieren:

Problemlose Python Lambda-Bereitstellung [Tutorial + Skript]

joarleymoraes
quelle
2
Toller Beitrag, aber ich vermisse Details zum schwierigsten Teil, nämlich wie man native Bibliotheken verpackt. Es ist wirklich nicht normal, wie komplex das ist
JohnAndrews
9

Hier ist ein kurzer Schritt durch.

Angenommen, Sie haben einen Ordner deploymit Ihrer Lambda-Datei im Aufruf lambda_function.py. Nehmen wir an, diese Datei sieht ungefähr so ​​aus. ( p1und p2stellen Pakete von Drittanbietern dar.)

import p1
import p2

def lambda_handler(event, context):
    # more code here

    return {
        "status": 200,
        "body" : "Hello from Lambda!",
    }

Für jede Abhängigkeit von Drittanbietern müssen Sie pip install <third-party-package> --target .aus dem deployOrdner heraus.

pip install p1 --target .
pip install p2 --target .

Sobald Sie dies getan haben, sehen Sie hier, wie Ihre Struktur aussehen sollte.

deploy/
├── lambda_function.py
├── p1/
   ├── __init__.py
   ├── a.py
   ├── b.py
   └── c.py
└── p2/
    ├── __init__.py
    ├── x.py
    ├── y.py
    └── z.py

Schließlich müssen Sie den zipgesamten Inhalt des deployOrdners in eine komprimierte Datei umwandeln. Auf einem Mac oder Linux würde der Befehl zip -r ../deploy.zip *aus dem deployOrdner heraus aussehen . Beachten Sie, dass das -rFlag für rekursive Unterordner gilt.

Die Struktur der Datei-Zip-Datei sollte den ursprünglichen Ordner widerspiegeln.

deploy.zip/
├── lambda_function.py
├── p1/
   ├── __init__.py
   ├── a.py
   ├── b.py
   └── c.py
└── p2/
    ├── __init__.py
    ├── x.py
    ├── y.py
    └── z.py

Laden Sie die Zip-Datei hoch und geben Sie <file_name>.<function_name>an, welche Lambda in Ihren Prozess eingehen soll, wie im lambda_function.lambda_handlerobigen Beispiel.

openwonk
quelle
1
Darüber hinaus komprimieren Sie NICHT den gesamten Ordner wie zip -r deploy.zip deploy. Dadurch wird ein Bereitstellungsordner in der Zip-Datei erstellt.
Openwonk
8

Ich fand diesen schwierigen Weg, nachdem ich alle oben genannten Lösungen ausprobiert hatte. Wenn Sie Unterverzeichnisse in der Zip-Datei verwenden, stellen Sie sicher, dass Sie die __init__.pyDatei in jedes der Unterverzeichnisse aufnehmen, und das hat bei mir funktioniert.

KApuri
quelle
7

Ich hatte auch den Fehler. Es stellt sich heraus, dass meine Zip-Datei den übergeordneten Code-Ordner enthält. Wenn ich unzipund die Zip-Datei inspiziere, befindet sich die lambda_functionDatei im übergeordneten Ordner ./lambda.

Verwenden Sie den zipBefehl, um den Fehler zu beheben:

zip -r ../lambda.zip ./*
Joe
quelle
1
Führen Sie die Zip-Datei in Ihrem Code-Ordner aus. Mein Fall hier, CD Lambda && zip -r ../lambda.zip ./*
Joe
3

Im lambda_handlerFormat muss sein lambda_filename.lambda_functionName. Angenommen, Sie möchten die lambda_handlerFunktion ausführen und sie ist in lambda_fuction.py, dann lautet Ihr Handlerformat lambda_function.lambda_handler.

Ein weiterer Grund für diesen Fehler sind Modulabhängigkeiten.

Sie lambda_fuction.pymüssen sich im Stammverzeichnis der Zip-Datei befinden.

PKP
quelle
2

@nithin, AWS hat das layersKonzept für LambdaFunktionen veröffentlicht. Sie können Ihre Ebene erstellen und dort so viele Bibliotheken hochladen, wie Sie die Ebene mit den Lambda-Funktionen verbinden können. Für weitere Informationen: https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html

muTheTechie
quelle
1

Ich bin auf dasselbe Problem gestoßen. Dies war eine Übung im Rahmen eines Tutorials auf lynda.com, wenn ich mich nicht irre. Der Fehler, den ich gemacht habe, war, dass ich die Laufzeit nicht als Python 3.6 ausgewählt habe, was eine Option in der Lamda-Funktionskonsole ist.

Nadeem
quelle
1

Eine Perspektive von 2019:

AWS Lambda unterstützt jetzt Python 3.7, das von vielen Personen (einschließlich mir) als Laufzeit für Inline-Lambdas verwendet wird.

Dann musste ich eine externe Abhängigkeit importieren und folgte AWS Docs als OP. (lokale Installation -> Zip -> Upload).

Ich hatte den Fehler im Importmodul und stellte fest, dass mein lokaler PC Python 2.7 als Standard-Python hatte. Als ich pip aufrief, wurde meine Abhängigkeit für Python 2.7 installiert.

Also habe ich lokal auf die Python-Version umgestellt, die der ausgewählten Laufzeitversion in der Lambda-Konsole entspricht, und dann die externen Abhängigkeiten neu installiert. Dies löste das Problem für mich. Z.B:

$ python3 -m pip install --target path/to/lambda_file <external_dependency_name>
l001d
quelle
0

Sie müssen alle Anforderungen komprimieren, verwenden Sie dieses Skript

#!/usr/bin/env bash
rm package.zip
mkdir package
pip install -r requirements.txt --target package
cat $1 > package/lambda_function.py
cd package
zip -r9 "../package.zip" .
cd ..
rm -rf package

benutzen mit:

package.sh <python_file>
Uri Goren
quelle
0

Teilen Sie meine Lösung für das gleiche Problem, nur für den Fall, dass es jemandem hilft.

Problem: Ich habe die Fehlermeldung "[ERROR] Runtime.ImportModuleError: Modul 'lambda_function' kann nicht importiert werden: Kein Modul mit dem Namen 'StringIO'" beim Ausführen des in AWS-Artikel [2] bereitgestellten aws-big-data-blog-Codes [1].

Lösung: Die Laufzeit wurde von Python 3.7 auf Python 2.7 geändert

[1] - https://github.com/bsnively/aws-big-data-blog/blob/master/aws-blog-vpcflowlogs-athena-quicksight/CloudwatchLogsToFirehose/lambdacode.py [2] - https: // aws .amazon.com / blogs / big-data / analyse-vpc-flussprotokolle-mit-amazon-kinesis-firehose-amazon-athena-und-amazon-quicksight /

user72789
quelle
Für mich war es umgekehrt (2.7 -> 3.8)
Demonicdaron
0

Sie können Ihre Lambda-Funktion so konfigurieren, dass zusätzlicher Code und Inhalt in Form von Ebenen abgerufen werden. Eine Ebene ist ein ZIP-Archiv, das Bibliotheken, eine benutzerdefinierte Laufzeit oder andere Abhängigkeiten enthält. Mit Layern können Sie Bibliotheken in Ihrer Funktion verwenden, ohne sie in Ihr Bereitstellungspaket aufnehmen zu müssen. Mit Ebenen können Sie Ihr Bereitstellungspaket klein halten, was die Entwicklung erleichtert.

Verweise:-

  1. https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html
  2. https://towardsdatascience.com/introduction-to-amazon-lambda-layers-and-boto3-using-python3-39bd390add17
Rahul Satal
quelle
0

Mein Problem war, dass sich die .py-Datei und die Abhängigkeiten nicht im "root" -Verzeichnis der Zip-Datei befanden. zB muss der Pfad der Bibliotheken und der Lambda-Funktion .py sein:

<lambda_function_name>.py
<name of library>/foo/bar/

nicht

/foo/bar/<name of library>/foo2/bar2

Beispielsweise:

drwxr-xr-x  3.0 unx        0 bx stor 20-Apr-17 19:43 boto3/ec2/__pycache__/
-rw-r--r--  3.0 unx      192 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/__init__.cpython-37.pyc
-rw-r--r--  3.0 unx      758 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/deletetags.cpython-37.pyc
-rw-r--r--  3.0 unx      965 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/createtags.cpython-37.pyc
-rw-r--r--  3.0 unx     7781 tx defN 20-Apr-17 20:33 download-cs-sensors-to-s3.py
Lobi
quelle
0

Gehen Sie tatsächlich zu dem Hauptordner (Bereitstellungspaket), den Sie komprimieren möchten.

Wählen Sie in diesem Ordner alle Dateien aus, erstellen Sie die Zip-Datei und laden Sie diese Zip-Datei hoch

MUHAMMAD ZEESHAN
quelle