Error del módulo de importación de AWS Lambda en python

93

Estoy creando un paquete de implementación de Python de AWS Lambda. Estoy usando una solicitud de dependencia externa. Instalé la dependencia externa usando la documentación de AWS http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html . A continuación se muestra mi código de 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

Creó Zip el contenido del directorio project-dir y lo cargó en lambda (Zip el contenido del directorio, no el directorio). Cuando ejecuto la función, obtengo el error mencionado a continuación.

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

Amablemente ayúdame a depurar el error.

Nithin K Anil
fuente
¿Es tu código completo? Por el error, parece que en algún lugar querría algo import lambda_functionque no se encuentra. ¿Quizás quieres from future import lambda_function? O simplemente instale pip lambda_function en la línea cmd.
Berci
@Berci Estoy ejecutando este código Python en la plataforma AWS. No puedo usar pip. en cualquier lugar de mi código estoy usando lambda_function. SI copio y pego el mismo código en la consola de AWS, funcionará
Nithin K Anil
Vea el último comentario en este hilo , ¿tal vez se aplique a usted?
kwinkunks
@kwinkunks Lo intenté. ¡En realidad estoy comprimiendo el contenido, no el directorio!
Nithin K Anil
2
Supongo que la opción "controlador" en su función es incorrecta. Verifique que su nombre de archivo llamado "lambda_function.py" y el método del controlador sea "lambda_handler"
Vor

Respuestas:

110

El error se debió al nombre de archivo de la función lambda. Al crear la función lambda, solicitará el controlador de funciones Lambda. Tiene que nombrarlo como su Python_File_Name.Method_Name . En este escenario, lo nombré lambda.lambda_handler (lambda.py es el nombre del archivo).

A continuación, encontrará la instantánea. ingrese la descripción de la imagen aquí

Nithin K Anil
fuente
1
Mi código está solo en lambda como código, no como un archivo.
Ben Wheeler
4
@BenWheeler: Aunque es un código en línea, es en un archivo en el que lo escribe. Puede ver el nombre del archivo y la estructura completa del directorio a la izquierda de la ventana.
Vineeth
Así que había nombrado mi código como "lambda_function.py", ¿debería nombrar el controlador como Python_lambda_function.lambda_handler?
RB17
@RahulBanerjee No. lo llamarías lambda_function.lambda_handler
Dinesh
90

Si está cargando un archivo zip. Asegúrese de comprimir el contenido del directorio y no el directorio en sí.

2ank3th
fuente
2
Al comprimir, ¡asegúrese de usar la bandera -r también!
Grant Robert Smith
@ 2ank3th eres el mejor
Sethuraman Srinivasan
Gracias por esto.
JamesG
24

Otra fuente de este problema son los permisos sobre el archivo comprimido. Se DEBE ser al menos legible en todo el mundo. (min chmod 444)

Ejecuté lo siguiente en el archivo de Python antes de comprimirlo y funcionó bien.

chmod u=rwx,go=r
Catalin Ciurea
fuente
4
Esta. Estaba usando ZipFile de Python para empaquetar programáticamente las funciones lambda en el ZIP, por defecto tiene lo 0600que, como mencionas, no es suficiente. Además, el editor de código fuente de Lambda integrado (en la página web de Amazon) leerá felizmente el archivo sin advertir sobre problemas de permisos.
Gracias
2
Segundo. Lo hice funcionar estableciendo permisos de archivo usando el método que se muestra aquí: stackoverflow.com/a/434689/931277
dokkaebi
15

Encontré la respuesta de Nithin muy útil. Aquí hay un recorrido específico:

Busque estos valores:

  1. El nombre de la función lambda_handler en su secuencia de comandos de Python. El nombre que se utiliza en los ejemplos de AWS es "lambda_handler" y se parece a "def lambda_handler (evento, contexto)". En este caso, el valor es "lambda_handler"
  2. En el panel de Lambda, busque el nombre del controlador en el cuadro de texto "Controlador" de la sección "Configuración" en el panel de control de Lambda para la función (que se muestra en la captura de pantalla de Nithin). Mi nombre predeterminado era "lambda_function.lambda_handler".
  3. El nombre de su secuencia de comandos de Python. Digamos que es "cool.py"

Con estos valores, necesitaría cambiar el nombre del controlador (que se muestra en la captura de pantalla) a "cool.lambda_handler". Esta es una forma de deshacerse del mensaje de error "No se puede importar el módulo 'lambda_function'". Si tuviera que cambiar el nombre del controlador en su script de Python a "sup", entonces necesitaría cambiar el nombre del controlador en el panel de Lambda a "cool.sup"

usuario3303554
fuente
11

Hay muchas trampas al crear paquetes de implementación para AWS Lambda (para Python). He pasado horas y horas depurando sesiones hasta que encontré una fórmula que rara vez falla.

He creado un script que automatiza todo el proceso y, por lo tanto, lo hace menos propenso a errores. También escribí un tutorial que explica cómo funciona todo. Es posible que desee comprobarlo:

Implementación de Python Lambda sin complicaciones [Tutorial + Script]

joarleymoraes
fuente
2
Gran publicación, pero echo de menos detalles sobre la parte más difícil, que es cómo empaquetar bibliotecas nativas. Realmente no es normal lo complejo que es esto
JohnAndrews
10

Aquí hay un paso rápido.

Suponga que tiene una carpeta llamada deploy, con su archivo lambda dentro de la llamada lambda_function.py. Supongamos que este archivo se parece a esto. ( p1y p2representan paquetes de terceros).

import p1
import p2

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

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

Para cada dependencia de terceros, debe hacerlo pip install <third-party-package> --target .desde la deploycarpeta.

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

Una vez que haya hecho esto, así es como debería verse su estructura.

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

Finalmente, necesita ziptodos los contenidos dentro de la deploycarpeta en un archivo comprimido. En Mac o Linux, el comando se vería zip -r ../deploy.zip *dentro de la deploycarpeta. Tenga en cuenta que la -rbandera es para subcarpetas recursivas.

La estructura del archivo zip debe reflejar la carpeta original.

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

Cargue el archivo zip y especifique <file_name>.<function_name>que Lambda ingrese en su proceso, como lambda_function.lambda_handleren el ejemplo anterior.

openwonk
fuente
1
Además, NO comprima toda la carpeta como zip -r deploy.zip deploy. Esto creará una carpeta de implementación dentro del archivo zip.
openwonk
9

Encontré esta manera difícil después de probar todas las soluciones anteriores. Si está utilizando subdirectorios en el archivo zip, asegúrese de incluir el __init__.pyarchivo en cada uno de los subdirectorios y eso funcionó para mí.

KApuri
fuente
7

Yo también tuve el error. Resulta que mi archivo zip incluye la carpeta principal del código. Cuando unzipinspecciono el archivo zip, el lambda_functionarchivo está en la carpeta principal ./lambda.

Utilice el zipcomando, corrija el error:

zip -r ../lambda.zip ./*
Joe
fuente
1
ejecute el zip dentro de su carpeta de código. mi caso aquí, cd lambda && zip -r ../lambda.zip ./*
Joe
4

En lambda_handlerel formato debe ser lambda_filename.lambda_functionName. Suponiendo que desea ejecutar la lambda_handlerfunción y está en lambda_fuction.py, entonces su formato de controlador eslambda_function.lambda_handler .

Otra razón para obtener este error son las dependencias de los módulos.

Su lambda_fuction.pydebe estar en el directorio raíz del archivo zip.

PKP
fuente
2

Una perspectiva desde 2019:

AWS Lambda ahora es compatible con Python 3.7, que muchas personas (incluido yo mismo) eligen usar como tiempo de ejecución para lambdas en línea.

Luego tuve que importar una dependencia externa y seguí AWS Docs como se refiere al OP. (instalación local -> zip -> cargar).

Tuve el error del módulo de importación y me di cuenta de que mi PC local tenía Python 2.7 como Python predeterminado. Cuando invoqué pip, instaló mi dependencia para Python 2.7.

Así que cambié localmente a la versión de Python que coincide con la versión de tiempo de ejecución seleccionada en la consola lambda y luego reinstalé las dependencias externas. Esto resolvió mi problema. P.ej:

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

Me encontré con el mismo problema, este fue un ejercicio como parte de un tutorial en lynda.com si no me equivoco. El error que cometí fue no seleccionar el tiempo de ejecución como Python 3.6, que es una opción en la consola de funciones de lamda.

Nadeem
fuente
1

El problema aquí que la versión de Python usó para construir las dependencias de su función Lambda (en su propia máquina) es diferente a la versión de Python seleccionada para su función Lambda. Este caso es común, especialmente si la biblioteca Numpy forma parte de sus dependencias.

Ejemplo: la versión de Python de su máquina: 3.6 ---> Lambda Python versión 3.6

Sharhabeel Hamdan
fuente
0

Necesita comprimir todos los requisitos, use este 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

usar con:

package.sh <python_file>
Uri Goren
fuente
0

Compartiendo mi solución para el mismo problema, por si acaso ayuda a alguien.

Problema: Recibí el error: "[ERROR] Runtime.ImportModuleError: No se puede importar el módulo 'lambda_function': No hay módulo llamado 'StringIO'" mientras se ejecutaba el código aws-big-data-blog [1] proporcionado en el artículo de AWS [2].

Solución: se cambió el tiempo de ejecución de Python 3.7 a 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 / análisis-vpc-flow-logs-with-amazon-kinesis-firehose-amazon-athena-and-amazon-quicksight /

user72789
fuente
Fue al revés para mí (2.7 -> 3.8)
demonicdaron
0

Puede configurar su función Lambda para extraer código y contenido adicionales en forma de capas. Una capa es un archivo ZIP que contiene bibliotecas, un tiempo de ejecución personalizado u otras dependencias. Con capas, puede usar bibliotecas en su función sin necesidad de incluirlas en su paquete de implementación. Las capas le permiten mantener su paquete de implementación pequeño, lo que facilita el desarrollo.

Referencias: -

  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
fuente
0

Mi problema fue que el archivo .py y las dependencias no estaban en el directorio "raíz" del zip. por ejemplo, la ruta de las bibliotecas y la función lambda .py debe ser:

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

no

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

Por ejemplo:

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
fuente
0

En realidad, vaya a la carpeta principal (paquete de implementación) que desea comprimir,

Dentro de esa carpeta, seleccione todos los archivos y luego cree el zip y cargue ese zip

MUHAMMAD ZEESHAN
fuente
0

Por favor agregue debajo uno después Import requests

import boto3

Lo que puedo ver que falta en su código.

Mrinal
fuente