Ich erstelle ein AWS Lambda Python-Bereitstellungspaket. Ich verwende eine externe Abhängigkeitsanfrage. 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 den Zip des Inhalts des Projektverzeichnisses und wird in den Lambda hochgeladen (Zip des Verzeichnisinhalts, nicht des Verzeichnisses). Beim Ausführen der Funktion 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
Helfen Sie mir bitte, den Fehler zu debuggen.
Fehler war aufgrund des Dateinamens der Lambda-Funktion. Beim Erstellen der Lambda-Funktion wird nach dem Lambda-Funktionshandler gefragt. Sie müssen es als Ihren Python_File_Name.Method_Name bezeichnen. In diesem Szenario habe ich es als lambda.lambda_handler bezeichnet (lambda.py ist der Dateiname).
Wenn Sie eine ZIP-Datei hochladen. Stellen Sie sicher, dass Sie den Inhalt des Verzeichnisses und nicht das Verzeichnis selbst komprimieren.
Eine weitere Ursache für dieses Problem sind die Berechtigungen für die Datei, die komprimiert wird. Es MUSS mindestens weltweit lesbar sein. (Mindest chmod 444
)
Ich habe die Datei python vor dem Zippen folgendermaßen ausgeführt und es hat einwandfrei funktioniert.
chmod u=rwx,go=r
Ich fand Nithins Antwort sehr hilfreich. Hier ist ein spezieller Rundgang:
Diese Werte nachschlagen:
Mit diesen Werten müssten Sie den Handler (im Screenshot gezeigt) in "cool.lambda_handler" umbenennen. Dies ist eine Möglichkeit, die fehlermeldung "Modul kann nicht importiert werden 'lambda_function'" loszuwerden. 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.
Es gibt so viele gotchas, wenn Sie Implementierungspakete für AWS Lambda (für Python) erstellen. Ich habe Stunden und Stunden damit verbracht, Sitzungen zu debuggen, bis ich eine Formel gefunden habe, die selten scheitert.
Ich habe ein Skript erstellt, das den gesamten Prozess automatisiert und 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]
Ich hatte auch die Fehlermeldung . Stellen Sie sich heraus, dass meine Zip-Datei den übergeordneten Code-Ordner enthält. Wenn ich unzip
und die ZIP-Datei untersuche, befindet sich die lambda_function
-Datei im übergeordneten Ordner ./lambda
.
Verwenden Sie den Befehl Zip
, um den Fehler zu beheben:
Zip -r ../lambda.Zip ./*
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__.py
-Datei in jedes der Unterverzeichnisse aufnehmen, und das hat für mich funktioniert.
Hier ist ein kurzer Schritt durch.
Angenommen, Sie haben einen Ordner namens deploy
mit Ihrer Lambda-Datei im Aufruf lambda_function.py
. Nehmen wir an, diese Datei sieht ungefähr so aus. (p1
und p2
stellen 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 .
im Ordner deploy
eingeben.
pip install p1 --target .
pip install p2 --target .
Sobald Sie dies getan haben, ist 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 Zip
den gesamten Inhalt des Ordners deploy
in eine komprimierte Datei umwandeln. Auf einem Mac oder Linux sieht der Befehl aus dem Ordner deploy
wie Zip -r ../deploy.Zip *
aus. Beachten Sie, dass das Flag -r
für rekursive Unterordner gilt.
Die Struktur der 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 den <file_name>.<function_name>
an, damit Lambda in Ihren Prozess eintritt, z. B. lambda_function.lambda_handler
für das obige Beispiel.
in lambda_handler muss das Format lambda_filename.lambda_functionName sein. Angenommen, Sie möchten die Funktion lambda_handler ausführen, und in lambda_fuction.py lautet Ihr Handler-Format "lambda_function.lambda_handler". Ein weiterer Grund für den Fehler sind Modulabhängigkeiten. Ihre Datei lambda_fuction.py muss sich im Stammverzeichnis von Zip befinden.
@nithin, AWS hat layers
-Konzept in Lambda
-Funktionen veröffentlicht. Sie können Ihre Ebene erstellen und dort so viel hochladen wie Bibliotheken, und Sie können die Ebene dann mit den Lambda-Funktionen verbinden. Für weitere Informationen: https://docs.aws.Amazon.com/lambda/latest /dg/configuration-layers.html
Keine Notwendigkeit, dieses Chaos zu tun.
verwenden Sie Python-Lambda
https://github.com/nficano/python-lambda
mit einem einzigen Befehl wird pylambda deploy
it Ihre Funktion automatisch bereitstellen
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>
Eine Perspektive von 2019:
AWS Lambda unterstützt jetzt Python 3.7, das von vielen (einschließlich mir) als Laufzeit für Inline-Lambdas verwendet wird.
Dann musste ich eine externe Abhängigkeit importieren und folgte AWS Docs als das OP, auf das verwiesen wurde. (lokale Installation -> Zip -> Upload).
Ich hatte den Importmodulfehler und stellte fest, dass mein lokaler PC Python 2.7 als Standard-Python hatte. Als ich pip aufrief, installierte es meine Abhängigkeit für Python 2.7.
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>
Ich bin auf das gleiche Problem gestoßen, dies war eine Übung als Teil eines Tutorials auf lynda.com, wenn ich mich nicht irre. Der Fehler, den ich gemacht habe, war die Auswahl der Laufzeitumgebung nicht als Python 3.6, was eine Option in der Lamda-Funktionskonsole ist.