Ошибка модуля импорта AWS Lambda в Python

93

Я создаю пакет развертывания AWS Lambda python. Я использую один запрос внешней зависимости. Я установил внешнюю зависимость, используя документацию AWS http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html . Ниже мой код на 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

Создал Zip-архив для содержимого каталога project-dir и загрузил его в лямбда-архив (Zip-архив для содержимого каталога, а не для каталога). Когда я выполняю функцию, я получаю указанную ниже ошибку.

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

Пожалуйста, помогите мне отладить ошибку.

Нитин К Анил
источник
Это ваш полный код? По ошибке кажется, что где-то захочется import lambda_functionчего- то, чего не найдено. Может, хочешь from future import lambda_function? Или просто установите lambda_function в строке cmd.
Berci
@Berci Я запускаю этот код Python на платформе AWS. Я не могу использовать pip. в любом месте моего кода я использую lambda_function. ЕСЛИ я
скопирую и вставлю
Смотрите последний комментарий в этой ветке - может быть, относится к вам?
kwinkunks
@kwinkunks Я пробовал это. На самом деле я архивирую содержимое, а не каталог !!
Nithin K Anil
2
Я предполагаю, что опция "обработчик" в вашей функции неверна. Убедитесь, что ваше имя файла называется «lambda_function.py», а метод обработчика - «lambda_handler»
Вор,

Ответы:

110

Ошибка возникла из-за имени файла лямбда-функции. При создании лямбда-функции он запросит обработчик лямбда-функции. Вы должны назвать его своим Python_File_Name.Method_Name . В этом сценарии я назвал его lambda.lambda_handler (lambda.py - это имя файла).

Ниже приведен снимок. введите описание изображения здесь

Нитин К Анил
источник
1
Мой код - это просто лямбда как код, а не как файл.
Бен Уиллер
4
@BenWheeler: Несмотря на то, что это встроенный код, вы на самом деле пишете его в файл. Вы можете увидеть имя файла и всю структуру каталогов слева от окна.
Vineeth
Итак, я назвал свой код «lambda_function.py», должен ли я назвать обработчик Python_lambda_function.lambda_handler?
RB17
@RahulBanerjee: Нет, вы бы назвали это lambda_function.lambda_handler
Динеш
90

Если вы загружаете zip-файл. Убедитесь, что вы архивируете содержимое каталога, а не сам каталог.

2энк
источник
2
При архивировании убедитесь, что вы также используете флаг -r!
Грант Роберт Смит
@ 2ank3th ты лучший
Сетураман Сринивасан
Спасибо за это.
JamesG
24

Другой источник этой проблемы - права доступа к заархивированному файлу. Он ДОЛЖЕН быть доступен для чтения по крайней мере во всем мире. (мин chmod 444)

Я запустил следующее в файле python перед его архивированием, и он работал нормально.

chmod u=rwx,go=r
Каталин Чуреа
источник
4
Этот. Я использовал Python ZipFile, чтобы программно упаковать лямбда-функции в ZIP-архив, по умолчанию 0600этого недостаточно. Кроме того, встроенный редактор исходного кода Lambda (на веб-странице Amazon) с радостью прочитает файл без предупреждения о проблемах с разрешениями.
cjhanks
2
Второй. Я заставил его работать, установив права доступа к файлам, используя метод, показанный здесь: stackoverflow.com/a/434689/931277
dokkaebi
15

Я нашел ответ Нитина очень полезным. Вот конкретное пошаговое руководство:

Найдите эти значения:

  1. Имя функции lambda_handler в вашем скрипте python. В примерах AWS используется имя «lambda_handler», похожее на «def lambda_handler (event, context)». В данном случае это значение "lambda_handler".
  2. На панели управления лямбда-выражением найдите имя обработчика в текстовом поле «Обработчик» в разделе «Конфигурация» на панели инструментов лямбда-выражения для функции (показано на снимке экрана Nithin). Мое имя по умолчанию было «lambda_function.lambda_handler».
  3. Имя вашего скрипта Python. Допустим, это "cool.py"

С этими значениями вам нужно будет переименовать обработчик (показанный на скриншоте) в "cool.lambda_handler". Это один из способов избавиться от сообщения об ошибке «Невозможно импортировать модуль lambda_function». Если бы вы переименовали обработчик в скрипте python на «sup», тогда вам нужно было бы переименовать обработчик на панели лямбда-анализа в «cool.sup»

user3303554
источник
11

При создании пакетов развертывания для AWS Lambda (для Python) существует так много ошибок . Я потратил часы и часы на сеансы отладки, пока не нашел формулу, которая редко дает сбой.

Я создал сценарий, который автоматизирует весь процесс и, следовательно, делает его менее подверженным ошибкам. Я также написал учебник, в котором объясняется, как все работает. Вы можете проверить это:

Беспроблемное развертывание Python Lambda [Учебное пособие + сценарий]

Joarleymoraes
источник
2
Отличный пост, но мне не хватает деталей о самой сложной части - о том, как упаковать собственные библиотеки. Это действительно ненормально, насколько это сложно
JohnAndrews
10

Вот быстрый шаг.

Предположим, у вас есть папка с именем deployс вашим лямбда-файлом внутри call lambda_function.py. Предположим, этот файл выглядит примерно так. ( p1и p2представляют собой сторонние пакеты.)

import p1
import p2

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

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

Для каждой сторонней зависимости вам необходимо pip install <third-party-package> --target .из deployпапки.

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

Как только вы это сделаете, вот как должна выглядеть ваша структура.

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

Наконец, вам нужно преобразовать zipвсе содержимое deployпапки в сжатый файл. На Mac или Linux команда будет выглядеть zip -r ../deploy.zip *внутри deployпапки. Обратите внимание, что этот -rфлаг предназначен для рекурсивных вложенных папок.

Структура ZIP-файла должна отражать исходную папку.

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

Загрузите zip-файл и укажите, как <file_name>.<function_name>Lambda будет использоваться в вашем процессе, как lambda_function.lambda_handlerв примере выше.

openwonk
источник
1
Кроме того, НЕ архивируйте всю папку, например zip -r deploy.zip deploy. Это создаст папку развертывания в zip-файле.
openwonk
9

Я нашел этот трудный путь после попытки всех вышеперечисленных решений. Если вы используете подкаталоги в zip-файле, убедитесь, что вы включили __init__.pyфайл в каждый из подкаталогов, и это сработало для меня.

КАПУРИ
источник
7

У меня тоже была ошибка. Оказалось, что мой zip-файл включает родительскую папку code. Когда я unzipпросматриваю zip-файл, он lambda_functionнаходится в родительской папке ./lambda.

Воспользуйтесь zipкомандой, исправьте ошибку:

zip -r ../lambda.zip ./*
Джо
источник
1
запустите zip внутри папки с кодом. мой случай здесь, cd lambda && zip -r ../lambda.zip ./*
Джо
4

В lambda_handlerформате должно быть lambda_filename.lambda_functionName. Предположим, вы хотите запустить lambda_handlerфункцию, и она находится в lambda_fuction.py, тогда ваш формат обработчика lambda_function.lambda_handler.

Еще одна причина появления этой ошибки - зависимости модулей.

Вы lambda_fuction.pyдолжны находиться в корневом каталоге zip-файла.

ПКП
источник
2

Взгляд с 2019 года:

AWS Lambda теперь поддерживает Python 3.7, который многие люди (включая меня) предпочитают использовать в качестве среды выполнения для встроенных лямбда-выражений.

Затем мне пришлось импортировать внешнюю зависимость, и я последовал за Документами AWS в качестве OP. (локальная установка -> zip -> загрузить).

У меня была ошибка модуля импорта, и я понял, что на моем локальном компьютере Python 2.7 установлен по умолчанию. Когда я вызвал pip, он установил мою зависимость для Python 2.7.

Поэтому я локально переключился на версию Python, которая соответствует выбранной версии среды выполнения в лямбда-консоли, а затем повторно установил внешние зависимости. Это решило проблему для меня. Например:

$ python3 -m pip install --target path/to/lambda_file <external_dependency_name>
l001d
источник
1

Я столкнулся с той же проблемой, если я не ошибаюсь, это было упражнение в рамках учебного курса на lynda.com. Ошибка, которую я сделал, заключалась в том, что я не выбрал среду выполнения как Python 3.6, которая является опцией в консоли функций lamda.

Надим
источник
1

Проблема здесь в том, что версия Python, используемая для построения зависимостей вашей лямбда-функции (на вашем собственном компьютере), отличается от выбранной версии Python для вашей лямбда-функции. Этот случай распространен, особенно если библиотека Numpy входит в ваши зависимости.

Пример: версия python для вашего компьютера: 3.6 ---> Lambda python версии 3.6

Шархабил Хамдан
источник
0

Вам нужно заархивировать все требования, используйте этот скрипт

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

использовать с:

package.sh <python_file>
Ури Горен
источник
0

Делюсь своим решением той же проблемы, на всякий случай, если это кому-то поможет.

Проблема: возникла ошибка: «[ОШИБКА] Runtime.ImportModuleError: Невозможно импортировать модуль lambda_function: Нет модуля с именем StringIO» при выполнении кода aws-big-data-blog [1], приведенного в статье AWS [2].

Решение: изменена среда выполнения с 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 / analysis-vpc-flow-logs-with-amazon-kinesis-firehose-amazon-athena-and-amazon-quicksight /

user72789
источник
Для меня было наоборот (2,7 -> 3,8)
demonicdaron
0

Вы можете настроить свою лямбда-функцию для получения дополнительного кода и содержимого в виде слоев. Слой - это ZIP-архив, содержащий библиотеки, настраиваемую среду выполнения или другие зависимости. Со слоями вы можете использовать библиотеки в своей функции без необходимости включать их в пакет развертывания. Слои позволяют сохранить небольшой размер пакета развертывания, что упрощает разработку.

Ссылки:-

  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

Моя проблема заключалась в том, что файл .py и зависимости не находились в «корневом» каталоге zip-архива. например, путь к библиотекам и лямбда-функции .py должен быть:

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

не

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

Например:

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

Фактически перейдите в основную папку (пакет развертывания), которую вы хотите заархивировать,

Внутри этой папки выберите все файлы, затем создайте zip и загрузите этот zip

МУХАММАД ЗИШАН
источник
0

Пожалуйста, добавьте ниже один после Import requests

import boto3

То, что я вижу, отсутствует в вашем коде.

Мринал
источник
-1

Не нужно делать такой беспорядок.

использовать python-lambda

https://github.com/nficano/python-lambda

с помощью одной команды pylambda deploy он автоматически развернет вашу функцию

мягкий зефир
источник