Erreur du module d'importation AWS Lambda dans Python

93

Je crée un package de déploiement AWS Lambda python. J'utilise une demande de dépendance externe. J'ai installé la dépendance externe à l'aide de la documentation AWS http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html . Voici mon code python.

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

Créé le Zip le contenu du répertoire project-dir et téléchargé vers le lambda (Zip le contenu du répertoire, pas le répertoire). Lorsque j'exécute la fonction, j'obtiens l'erreur mentionnée ci-dessous.

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

Veuillez m'aider à déboguer l'erreur.

Nithin K Anil
la source
Est-ce votre code complet? Par l'erreur, il semble que quelque chose voudrait quelque part import lambda_functionqui ne soit pas trouvé. Tu veux peut-être from future import lambda_function? Ou simplement pip installez lambda_function sur la ligne cmd.
Berci le
@Berci J'exécute ce code python sur la plateforme AWS. Je ne peux pas utiliser pip. n'importe où dans mon code, j'utilise lambda_function. Si je copie et collez le même code dans la console AWS, cela fonctionnera
Nithin K Anil
Voir le dernier commentaire sur ce fil - s'applique peut-être à vous?
kwinkunks
@kwinkunks j'ai essayé ça. En fait, je zippe le contenu pas le répertoire !!
Nithin K Anil
2
Je suppose que l'option "gestionnaire" de votre fonction est incorrecte. Vérifiez que votre nom de fichier appelé "lambda_function.py" et votre méthode de gestion sont "lambda_handler"
Vor le

Réponses:

110

L'erreur était due au nom de fichier de la fonction lambda. Lors de la création de la fonction lambda, il demandera un gestionnaire de fonction Lambda. Vous devez le nommer comme votre Python_File_Name.Method_Name . Dans ce scénario, je l'ai nommé lambda.lambda_handler (lambda.py est le nom du fichier).

Veuillez trouver ci-dessous le cliché. entrez la description de l'image ici

Nithin K Anil
la source
1
Mon code est juste en lambda en tant que code - pas en tant que fichier.
Ben Wheeler
4
@BenWheeler: Même s'il s'agit de code en ligne, c'est dans un fichier que vous l'écrivez. Vous pouvez voir le nom de fichier et toute la structure du répertoire à gauche de la fenêtre.
Vineeth
J'ai donc nommé mon code comme "lambda_function.py", dois-je nommer le gestionnaire comme Python_lambda_function.lambda_handler?
RB17
@RahulBanerjee Non, vous l'appeleriez comme lambda_function.lambda_handler
Dinesh
90

Si vous téléchargez un fichier zip. Assurez-vous que vous zippez le contenu du répertoire et non le répertoire lui-même.

2ank3e
la source
2
Lorsque vous zippez, assurez-vous que vous utilisez également l'indicateur -r!
Grant Robert Smith
@ 2ank3th vous êtes le meilleur
Sethuraman Srinivasan
Merci pour cela.
JamesG
24

Les autorisations sur le fichier compressé sont une autre source de ce problème. Il DOIT être au moins lisible dans le monde entier. (min chmod 444)

J'ai exécuté ce qui suit sur le fichier python avant de le compresser et cela a bien fonctionné.

chmod u=rwx,go=r
Catalin Ciurea
la source
4
Ce. J'utilisais ZipFile de Python pour intégrer par programme les fonctions lambda dans le ZIP, ce 0600qui, comme vous le mentionnez, ne suffit pas. De plus, l'éditeur de code source Lambda intégré (sur la page Web d'Amazon) lira volontiers le fichier sans avertissement des problèmes d'autorisations.
cjhanks
2
Seconde. Je l'ai fait fonctionner en définissant les autorisations de fichier en utilisant la méthode indiquée ici: stackoverflow.com/a/434689/931277
dokkaebi
15

J'ai trouvé la réponse de Nithin très utile. Voici une procédure pas à pas spécifique:

Recherchez ces valeurs:

  1. Le nom de la fonction lambda_handler dans votre script python. Le nom utilisé dans les exemples AWS est "lambda_handler" ressemblant à "def lambda_handler (event, context)". Dans ce cas, la valeur est "lambda_handler"
  2. Dans le tableau de bord Lambda, recherchez le nom du gestionnaire dans la zone de texte "Handler" de la section "Configuration" du tableau de bord lambda de la fonction (illustré dans la capture d'écran de Nithin). Mon nom par défaut était "lambda_function.lambda_handler".
  3. Le nom de votre script python. Disons que c'est "cool.py"

Avec ces valeurs, vous devrez renommer le gestionnaire (montré dans la capture d'écran) en "cool.lambda_handler". C'est une façon de se débarrasser du message d'erreur "Impossible d'importer le module 'lambda_function'". Si vous deviez renommer le gestionnaire dans votre script python en "sup", vous devrez alors renommer le gestionnaire dans le tableau de bord lambda en "cool.sup"

user3303554
la source
11

Il y a tellement de pièges lors de la création de packages de déploiement pour AWS Lambda (pour Python). J'ai passé des heures et des heures sur des sessions de débogage jusqu'à ce que je trouve une formule qui échoue rarement.

J'ai créé un script qui automatise l'ensemble du processus et le rend donc moins sujet aux erreurs. J'ai également écrit un tutoriel qui explique comment tout fonctionne. Tu voudras peut-être vérifier:

Déploiement sans tracas de Python Lambda [Tutoriel + Script]

joarleymoraes
la source
2
Excellent article mais je manque des détails sur la partie la plus difficile qui est de savoir comment empaqueter les bibliothèques natives. Ce n'est vraiment pas normal à quel point c'est complexe
JohnAndrews
10

Voici une étape rapide.

Supposons que vous ayez un dossier appelé deploy, avec votre fichier lambda à l'intérieur de l'appel lambda_function.py. Supposons que ce fichier ressemble à quelque chose comme ça. ( p1et p2représentent des packages tiers.)

import p1
import p2

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

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

Pour chaque dépendance tierce, vous devez pip install <third-party-package> --target .partir du deploydossier.

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

Une fois que vous avez fait cela, voici à quoi devrait ressembler votre structure.

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

Enfin, vous devez transformer ziptout le contenu du deploydossier dans un fichier compressé. Sur un Mac ou Linux, la commande ressemblerait à celle zip -r ../deploy.zip *du deploydossier. Notez que l' -rindicateur est pour les sous-dossiers récursifs.

La structure du fichier zip doit refléter le dossier d'origine.

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

Téléchargez le fichier zip et spécifiez <file_name>.<function_name>pour Lambda à entrer dans votre processus, comme dans lambda_function.lambda_handlerl'exemple ci-dessus.

openwonk
la source
1
De plus, ne fermez PAS le dossier entier comme zip -r deploy.zip deploy. Cela créera un dossier de déploiement dans le fichier zip.
openwonk
9

J'ai trouvé ce moyen difficile après avoir essayé toutes les solutions ci-dessus. Si vous utilisez des sous-répertoires dans le fichier zip, assurez-vous d'inclure le __init__.pyfichier dans chacun des sous-répertoires et cela a fonctionné pour moi.

KApuri
la source
7

J'ai eu l'erreur aussi. Il s'avère que mon fichier zip comprend le dossier parent de code. Lorsque unzipj'inspecte le fichier zip, le lambda_functionfichier est sous le dossier parent ./lambda.

Utilisez la zipcommande, corrigez l'erreur:

zip -r ../lambda.zip ./*
Joe
la source
1
exécutez le zip dans votre dossier de code. mon cas ici, cd lambda && zip -r ../lambda.zip ./*
Joe
4

Dans lambda_handlerle format doit être lambda_filename.lambda_functionName. Supposons que vous souhaitiez exécuter la lambda_handlerfonction et qu'elle soit lambda_fuction.pyactive, le format de votre gestionnaire est lambda_function.lambda_handler.

Une autre raison pour obtenir cette erreur est les dépendances de module.

Votre lambda_fuction.pydoit être dans le répertoire racine du fichier zip.

PKP
la source
2

@nithin, AWS a publié un layersconcept à l'intérieur des Lambdafonctions. Vous pouvez créer votre couche et là, vous pouvez télécharger autant que des bibliothèques, puis vous pouvez connecter la couche avec les fonctions lambda. Pour plus de détails: https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html

muTheTechie
la source
2

Une perspective de 2019:

AWS Lambda prend désormais en charge Python 3.7, que de nombreuses personnes (y compris moi-même) choisissent d'utiliser comme environnement d'exécution pour les lambdas en ligne.

Ensuite, j'ai dû importer une dépendance externe et j'ai suivi AWS Docs en tant qu'OP désigné. (installation locale -> zip -> téléchargement).

J'ai eu l'erreur de module d'importation et j'ai réalisé que mon PC local avait Python 2.7 comme Python par défaut. Lorsque j'ai appelé pip, il a installé ma dépendance pour Python 2.7.

J'ai donc basculé localement vers la version Python qui correspond à la version d'exécution sélectionnée dans la console lambda, puis réinstallé les dépendances externes. Cela a résolu le problème pour moi. Par exemple:

$ python3 -m pip install --target path/to/lambda_file <external_dependency_name>
l001d
la source
1

J'ai rencontré le même problème, c'était un exercice dans le cadre d'un tutoriel sur lynda.com si je ne me trompe pas. L'erreur que j'ai commise a été de ne pas sélectionner le runtime comme Python 3.6 qui est une option dans la console de fonction lamda.

Nadeem
la source
1

Le problème ici que la version Python utilisée pour créer vos dépendances de fonction Lambda (sur votre propre machine) est différente de la version Python sélectionnée pour votre fonction Lambda. Ce cas est courant en particulier si la bibliothèque Numpy fait partie de vos dépendances.

Exemple: la version python de votre machine: 3.6 ---> Lambda python version 3.6

Sharhabeel Hamdan
la source
0

Vous devez compresser toutes les exigences, utilisez ce script

#!/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

utiliser avec:

package.sh <python_file>
Uri Goren
la source
0

Partager ma solution pour le même problème, juste au cas où cela aiderait quelqu'un.

Problème: j'ai eu une erreur: "[ERROR] Runtime.ImportModuleError: Impossible d'importer le module 'lambda_function': aucun module nommé 'StringIO'" lors de l'exécution du code aws-big-data-blog [1] fourni dans l'article AWS [2].

Solution: Runtime changé de Python 3.7 à Python 2.7

[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-flow-logs-avec-amazon-kinesis-firehose-amazon-athena-and-amazon-quicksight /

user72789
la source
C'était l'inverse pour moi (2,7 -> 3,8)
demonicdaron
0

Vous pouvez configurer votre fonction Lambda pour extraire du code et du contenu supplémentaires sous la forme de couches. Une couche est une archive ZIP contenant des bibliothèques, un environnement d'exécution personnalisé ou d'autres dépendances. Avec les couches, vous pouvez utiliser des bibliothèques dans votre fonction sans avoir besoin de les inclure dans votre package de déploiement. Les couches vous permettent de réduire la taille de votre package de déploiement, ce qui facilite le développement.

Références:-

  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
la source
0

Mon problème était que le fichier .py et les dépendances n'étaient pas dans le répertoire «racine» du zip. Par exemple, le chemin des bibliothèques et de la fonction lambda .py doit être:

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

ne pas

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

Par exemple:

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
la source
0

En fait, allez dans le dossier principal (package de déploiement) que vous souhaitez compresser,

Dans ce dossier, sélectionnez tous les fichiers, puis créez le zip et téléchargez ce zip

MUHAMMAD ZEESHAN
la source
0

Veuillez ajouter ci-dessous un après Import requests

import boto3

Ce que je peux voir qui manque dans votre code.

Mrinal
la source