Błąd modułu importu AWS Lambda w Pythonie


93

Tworzę pakiet wdrożeniowy AWS Lambda Python. Używam jednego zewnętrznego żądania zależności. Zainstalowałem zewnętrzną zależność, korzystając z dokumentacji AWS http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html . Poniżej znajduje się mój kod w Pythonie.

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

Utworzono Zip zawartość katalogu project-dir i przesłano do lambda (Zip zawartość katalogu, a nie katalog). Kiedy wykonuję funkcję, pojawia się poniższy błąd.

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

Prosimy o pomoc w usunięciu błędu.


Czy to Twój pełny kod? Przez błąd wydaje się, że gdzieś chciałoby się coś, import lambda_functionczego nie znaleziono. Może chcesz from future import lambda_function? Lub po prostu pip zainstaluj lambda_function w linii cmd.
Berci,

@Berci Jestem uruchamiany na platformie AWS w języku Python. Nie mogę użyć pip. gdziekolwiek w moim kodzie używam lambda_function. JEŚLI
skopiuję, wklejam

Zobacz ostatni komentarz w tym wątku - może dotyczy Ciebie?
kwinkunks

@kwinkunks Próbowałem tego. Właściwie spakuję zawartość, a nie katalog !!
Nithin K Anil

2
Domyślam się, że opcja „handler” w twojej funkcji jest nieprawidłowa. Sprawdź, czy nazwa pliku o nazwie „lambda_function.py” i metoda obsługi to „lambda_handler”
Vor,

Odpowiedzi:


110

Błąd spowodowany nazwą pliku funkcji lambda. Podczas tworzenia funkcji lambda zapyta o handler funkcji lambda. Musisz nadać mu nazwę Python_File_Name.Method_Name . W tym scenariuszu nazwałem go jako lambda.lambda_handler (lambda.py to nazwa pliku).

Poniżej migawka. wprowadź opis obrazu tutaj


1
Mój kod jest po prostu w lambdzie jako kod - nie jako plik.
Ben Wheeler

4
@BenWheeler: Mimo że jest to kod wbudowany, zapisujesz go w pliku. Możesz zobaczyć nazwę pliku i całą strukturę katalogów po lewej stronie okna.
Vineeth

Więc nazwałem swój kod jako „lambda_function.py”, czy powinienem nazwać program obsługi jako Python_lambda_function.lambda_handler?
RB17

@RahulBanerjee Nie. Nazwałbyś to lambda_function.lambda_handler
Dinesh


24

Innym źródłem tego problemu są uprawnienia do spakowanego pliku. To musi być co najmniej na całym świecie czytelny. (min chmod 444)

Uruchomiłem następujące polecenie na pliku Pythona przed spakowaniem go i działało dobrze.

chmod u=rwx,go=r

4
To. Używałem Pythona ZipFile do programowego spakowania funkcji lambda do ZIP, domyślnie posiadanie 0600tego, jak wspomniałeś, nie wystarczy. Ponadto zintegrowany edytor kodu źródłowego Lambda (na stronie internetowej Amazon) z przyjemnością odczyta plik bez ostrzeżenia o problemach z uprawnieniami.
cjhanks

2
Druga. Mam to działające, ustawiając uprawnienia do plików za pomocą metody pokazanej tutaj: stackoverflow.com/a/434689/931277
dokkaebi

15

Odpowiedź Nithina okazała się bardzo pomocna. Oto konkretny przewodnik:

Wyszukaj te wartości:

  1. Nazwa funkcji lambda_handler w skrypcie w Pythonie. Nazwa użyta w przykładach AWS to „lambda_handler” przypominająca „def lambda_handler (zdarzenie, kontekst)”. W tym przypadku wartością jest „lambda_handler”
  2. Na pulpicie Lambda znajdź nazwę Handler w polu tekstowym "Handler" w sekcji "Konfiguracja" na pulpicie lambda dla funkcji (pokazane na zrzucie ekranu Nithina). Moja domyślna nazwa to „lambda_function.lambda_handler”.
  3. Nazwa twojego skryptu w Pythonie. Powiedzmy, że to „cool.py”

Mając te wartości, należałoby zmienić nazwę programu obsługi (pokazaną na zrzucie ekranu) na „cool.lambda_handler”. Jest to jeden ze sposobów na pozbycie się komunikatu o błędzie „Nie można zaimportować modułu 'lambda_function'”. Jeśli miałbyś zmienić nazwę handlera w swoim skrypcie Pythona na "sup", to musiałbyś zmienić nazwę handlera w dashboardzie lambda na "cool.sup"


11

Podczas tworzenia pakietów wdrożeniowych dla AWS Lambda (dla Pythona) jest tak wiele problemów . Spędziłem wiele godzin na sesjach debugowania, dopóki nie znalazłem formuły, która rzadko zawodzi.

Stworzyłem skrypt, który automatyzuje cały proces i dzięki temu jest mniej podatny na błędy. Napisałem również poradnik wyjaśniający, jak wszystko działa. Możesz to sprawdzić:

Bezproblemowe wdrażanie Lambda w języku Python [samouczek + skrypt]


2
Świetny post, ale brakuje mi szczegółów najtrudniejszej części, czyli sposobu pakowania natywnych bibliotek. To naprawdę nie jest normalne, jak skomplikowane to jest
JohnAndrews

10

Oto szybki krok.

Załóżmy, że masz folder o nazwie deploy, z plikiem lambda wewnątrz wywołania lambda_function.py. Załóżmy, że ten plik wygląda mniej więcej tak. ( p1i p2reprezentują pakiety stron trzecich).

import p1
import p2

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

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

W przypadku każdej zależności innej firmy musisz przejść pip install <third-party-package> --target .z poziomu deployfolderu.

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

Gdy to zrobisz, oto jak powinna wyglądać twoja struktura.

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

Na koniec musisz zipcałą zawartość deployfolderu do skompresowanego pliku. Na komputerze Mac lub Linux polecenie wyglądałoby jak zip -r ../deploy.zip *z deployfolderu. Zauważ, że -rflaga dotyczy rekurencyjnych podfolderów.

Struktura pliku zip powinna odzwierciedlać oryginalny folder.

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

Prześlij plik zip i określ <file_name>.<function_name>dla Lambda, aby wejść do twojego procesu, tak jak lambda_function.lambda_handlerw powyższym przykładzie.


1
Ponadto NIE ZAPAKUJ całego folderu, np zip -r deploy.zip deploy. Spowoduje to utworzenie folderu wdrażania w pliku zip.
openwonk

9

Po wypróbowaniu wszystkich powyższych rozwiązań okazało się to trudne. Jeśli używasz podkatalogów w pliku zip, upewnij się, że umieściłeś __init__.pyplik w każdym z podkatalogów i to zadziałało.


7

Ja też miałem błąd. Okazuje się, że mój plik zip zawiera folder nadrzędny kodu. Kiedy unzipsprawdzam plik zip, lambda_functionplik znajduje się w folderze nadrzędnym ./lambda.

Użyj zippolecenia, napraw błąd:

zip -r ../lambda.zip ./*

1
uruchom zip wewnątrz folderu kodu. moja sprawa tutaj, cd lambda && zip -r ../lambda.zip ./*
Joe

4

W lambda_handler formacie musi być lambda_filename.lambda_functionName. Przypuśćmy, że chcesz uruchomić lambda_handlerfunkcję i jest w lambda_fuction.py, to format twojego modułu obsługi to lambda_function.lambda_handler.

Innym powodem wystąpienia tego błędu są zależności modułów.

Twój lambda_fuction.pymusi znajdować się w katalogu głównym pliku zip.



2

Perspektywa z 2019 roku:

AWS Lambda obsługuje teraz Python 3.7, którego wiele osób (w tym ja) wybiera jako środowisko uruchomieniowe dla wbudowanych lambd.

Następnie musiałem zaimportować zewnętrzną zależność i postępowałem zgodnie z dokumentami AWS jako OP. (instalacja lokalna -> zip -> przesyłanie).

Wystąpił błąd modułu importu i zdałem sobie sprawę, że mój lokalny komputer ma Python 2.7 jako domyślny Python. Kiedy wywołałem pip, zainstalowałem moją zależność dla Pythona 2.7.

Więc przełączyłem się lokalnie na wersję Pythona, która pasuje do wybranej wersji środowiska uruchomieniowego w konsoli lambda, a następnie ponownie zainstalowałem zewnętrzne zależności. To rozwiązało problem. Na przykład:

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

1

Wpadłem na ten sam problem, to było ćwiczenie jako część samouczka na lynda.com, jeśli się nie mylę. Błąd, który popełniłem, polegał na tym, że nie wybrałem środowiska wykonawczego jako Python 3.6, co jest opcją w konsoli funkcji lamda.


1

Problem polega na tym, że wersja Pythona użyta do zbudowania zależności funkcji Lambda (na własnej maszynie) jest inna niż wybrana wersja Pythona dla funkcji Lambda. Ten przypadek jest powszechny, zwłaszcza jeśli biblioteka Numpy jest częścią twoich zależności.

Przykład: Wersja pythona twojego komputera: 3.6 ---> Lambda python w wersji 3.6


0

Musisz spakować wszystkie wymagania, użyj tego skryptu

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

używać z:

package.sh <python_file>

0

Udostępniam moje rozwiązanie tego samego problemu, na wszelki wypadek, gdyby to komukolwiek pomogło.

Problem: Wystąpił błąd: „[ERROR] Runtime.ImportModuleError: Nie można zaimportować modułu„ lambda_function ”: brak modułu o nazwie„ StringIO ”” podczas wykonywania kodu aws-big-data-blog [1] podanego w artykule AWS [2].

Rozwiązanie: Zmieniono środowisko wykonawcze z Python 3.7 na 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 / analysing-vpc-flow-logs-with-amazon-kinesis-firehose-amazon-athena-and-amazon-quicksight /


Dla mnie było odwrotnie (2,7 -> 3,8)
demonicdaron

0

Możesz skonfigurować swoją funkcję Lambda, aby pobierała dodatkowy kod i zawartość w postaci warstw. Warstwa to archiwum ZIP zawierające biblioteki, niestandardowe środowisko wykonawcze lub inne zależności. Dzięki warstwom możesz używać bibliotek w swojej funkcji bez konieczności dołączania ich do pakietu wdrożeniowego. Warstwy pozwalają zachować mały pakiet wdrożeniowy, co ułatwia programowanie.

Bibliografia:-

  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


0

Mój problem polegał na tym, że plik .py i zależności nie znajdowały się w katalogu głównym zip. np. ścieżka do bibliotek i funkcji lambda .py musi być:

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

nie

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

Na przykład:

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

0

Właściwie przejdź do głównego folderu (pakietu wdrożeniowego), który chcesz spakować,

Wewnątrz tego folderu wybierz wszystkie pliki, a następnie utwórz plik zip i prześlij ten plik zip


0

Dodaj poniżej jeden po Import requests

import boto3

To, co widzę, brakuje w Twoim kodzie.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.