Modul 'lambda_function' kann nicht importiert werden: Kein Modul mit dem Namen *

Oct 12 2020

Ich versuche, eine Python-Lambda-Funktion auszuführen, die zusätzliche Pakete verwendet. Wenn ich jedoch die ZIP-Datei auf die Lambda-Konsole hochlade, wird folgende Fehlermeldung angezeigt:

{
  "errorMessage": "Unable to import module 'lambda_function': No module named '*'",
  "errorType": "Runtime.ImportModuleError"
}

Ich habe diese Anweisungen befolgt: https://docs.aws.amazon.com/lambda/latest/dg/python-package.html#python-package-dependencies Das sagte mir, ich solle sicherstellen, dass sich meine Pakete in einem Verzeichnis befinden, das für meine Lambda-Funktion lokal ist:

~/my-function$ pip install --target ./package Pillow

Ich benutze kein Kissen. Dies ist Beispielcode von ihrer Site. Ich verwende auch kein Paket, auf das Sie bereits über Lambda zugreifen können. Es ist eines, das ich von Github bekommen habe und an meine App anhängen muss.

Zuerst hat das nicht funktioniert, also habe ich eine setup.cfgDatei erstellt und hinzugefügt in:

[install]
prefix= 

Wenn ich jetzt den pipBefehl zum Installieren auf dem Ziel verwende, funktioniert er (und fügt auch viele andere Ordner als mein Paket hinzu, aber ich habe angenommen, dass sie benötigt werden, also habe ich sie dort gelassen.

Wenn ich in das Verzeichnis gehe, ist das Paket dort.

Ich habe dann diese Antwort gefunden: https://stackoverflow.com/a/12493244/5675125 was darauf hindeutete, dass möglicherweise einige versteckte Dateien nicht enthalten waren, und so sollte ich sie komprimieren.

Wieder der gleiche Fehler.

Wie kann ich Lambda erkennen lassen, dass mein Paket da ist?

Antworten

1 Marcin Oct 12 2020 at 10:28

Wenn Sie Pillow benötigen, können Sie es am einfachsten in Ihrer Funktion verwenden, indem Sie ein beliebtes Repository mit öffentlichen Ebenen (einschließlich Kissen) wie keithrozario / Klayers on github verwenden. Um es zu verwenden, suchen Sie die ARN der Ebene basierend auf Ihrer Region . Die Liste der ARNs für Python 3.8 finden Sie hier .

Für us-east-1die für Python 3.7 hinzugefügte Ebene wäre beispielsweise:

Aktualisieren

Ich habe gerade die benutzerdefinierte Ebene mit erstellt instabotund kann bestätigen, dass sie funktioniert.

Die verwendete Technik umfasst das Docker-Tool, das im aktuellen AWS-Blog beschrieben wurde :

  • Wie erstelle ich eine Lambda-Ebene in einer simulierten Lambda-Umgebung mit Docker?

Daher habe ich diese Frage wie folgt überprüft :

  1. Erstellen Sie einen leeren Ordner, z mylayer.

  2. Gehen Sie zum Ordner und erstellen Sie eine requirements.txtDatei mit dem Inhalt von

instabot
  1. Führen Sie den folgenden Docker-Befehl aus:
docker run -v "$PWD":/var/task "lambci/lambda:build-python3.8" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.8/site-packages/; exit"
  1. Numpy entfernen

Das instaboterfordert numpywas sehr groß ist. Also entfernen wir es manuell, bevor wir eine Ebene erstellen. Wir werden numpystattdessen die von AWS bereitgestellte Ebene verwenden.

sudo rm -rvf ./python/lib/python3.8/site-packages/numpy*

Wenn wir numpy nicht entfernen, ist die Ebene> 50 MB groß.

  1. Ebene als Reißverschluss erstellen:
zip -9 -r mylayer.zip python 
  1. Erstellen Sie eine Lambda-Ebene basierend auf mylayer.zipder AWS-Konsole. Vergessen Sie nicht angeben Compatible runtimeszu python3.8.

  2. Fügen Sie Ihrer Funktion zwei Ebenen hinzu:

Der erste wird AWSLambda-Python38-SciPy1xvon AWS mit numpy bereitgestellt, während der zweite der oben erstellte ist. Ihre Funktion verwendet also zwei Ebenen.

  1. Testen Sie die Schicht in Lambda mit der folgenden Lambda-Funktion:
import json

from instabot import Bot

def lambda_handler(event, context):
    # TODO implement
    
    bot = Bot(base_path='/tmp')
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }