Impossibile importare il modulo 'lambda_function': nessun modulo denominato *

Oct 12 2020

Sto cercando di eseguire una funzione lambda python che utilizza pacchetti aggiuntivi. Tuttavia ogni volta che carico il file .zip sulla console lambda ricevo l'errore:

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

Ho seguito queste istruzioni: https://docs.aws.amazon.com/lambda/latest/dg/python-package.html#python-package-dependencies che mi ha detto di assicurarmi che i miei pacchetti fossero in una directory locale alla mia funzione lambda:

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

Non sto usando Pillow. Questo è un codice di esempio dal loro sito. Né sto utilizzando un pacchetto a cui puoi già accedere su Lambda. È uno che ho ottenuto da GitHub e devo collegarlo alla mia app.

All'inizio non funzionava, quindi ho creato un setup.cfgfile e aggiunto:

[install]
prefix= 

Ora, quando uso il pipcomando per l'installazione sulla destinazione, funziona (e aggiunge anche un sacco di altre cartelle oltre al mio pacchetto, ma ho pensato che fossero necessarie, quindi le ho lasciate lì.

Quando entro nella directory, il pacchetto è lì.

Ho quindi trovato questa risposta: https://stackoverflow.com/a/12493244/5675125 il che ha suggerito che forse alcuni file nascosti non venivano inclusi ed è così che dovrei comprimerli.

Di nuovo lo stesso errore.

Come faccio a far sì che lambda riconosca che il mio pacchetto è lì.

Risposte

1 Marcin Oct 12 2020 at 10:28

Se hai bisogno di Pillow, il modo più semplice per usarlo nella tua funzione è attraverso un popolare repository con livelli pubblici (incluso pillow) come keithrozario / Klayers su GitHub. Per usarlo, devi individuare l'ARN del livello in base alla tua regione . L'elenco degli ARN per python 3.8 è qui .

Ad esempio, per us-east-1il livello aggiunto per Python 3.7 sarebbe:

Aggiornare

Ho appena creato il livello personalizzato con instabote posso confermare che funziona.

La tecnica utilizzata include lo strumento Docker descritto nel recente blog AWS :

  • Come posso creare un livello Lambda utilizzando un ambiente Lambda simulato con Docker?

Quindi per questa domanda, l'ho verificato come segue:

  1. Crea una cartella vuota, ad es mylayer.

  2. Vai alla cartella e crea il requirements.txtfile con il contenuto di

instabot
  1. Esegui il seguente comando docker:
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. Rimuovi numpy

Il instabotrichiede numpyche è molto grande. Quindi lo rimuoviamo manualmente, prima di creare un livello. Utilizzeremo invece il numpylivello fornito da AWS.

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

Se non rimuoviamo numpy, il livello sarà> 50 MB.

  1. Crea livello come zip:
zip -9 -r mylayer.zip python 
  1. Crea un layer lambda basato su mylayer.zipnella Console AWS. Non dimenticare di specificare Compatible runtimesa python3.8.

  2. Aggiungi due livelli alla tua funzione:

Il primo è AWSLambda-Python38-SciPy1xfornito da AWS con numpy, mentre il secondo è quello che abbiamo creato sopra. Quindi la tua funzione utilizzerà due livelli.

  1. Testare il livello in lambda utilizzando la seguente funzione lambda:
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!')
    }