Невозможно импортировать etree lxml на aws lambda

{
  "errorMessage": "Unable to import module 'lambda_function': 
        cannot import name   'etree' from 'lxml' (/var/task/lxml/__init__.py)",
  "errorType": "Runtime.ImportModuleError"
}

Также пробовал https://gist.github.com/allen-munsch/ad8faf9c04b72aa8d0808fa8953bc639:

{
  "errorMessage": "Unable to import module 'lambda_function': 
     cannot import name 'etree' from 'lxml' 
     (/var/task/lxml-4.3.4-py3.6-linux-x86_64.egg/lxml/__init__.py)",
  "errorType": "Runtime.ImportModuleError"
}

Я использую Ubuntu 18.04 на своем локальном компьютере, а также пытался использовать образ «Amazon Linux» на экземпляре ec2 для сборки пакета.

Я также пробовал, находясь в активированном venv:

STATIC_DEPS=true pip3 install lxml --target ./package --upgrade --no-cache-dir

Я также попытался скопировать общие объектные файлы, основываясь на том, какие файлы были открыты при запуске скрипта с помощью strace:

#! /bin/bash

export Z=$(pwd)/ok-daily-lambda.zip
rm $Z
zip $Z lambda_function.py
zip $Z __init__.py

for dir in $(find venv_here/lib/python3.6/site-packages)
do
    if [ -d $dir ] ; then
        pushd $dir
        echo zip -r9 $Z $(pwd)
        zip -r9 $Z $(pwd)
        popd
    fi
done

export LIBD=$(pwd)/lib
mkdir -p $LIBD

cp "/home/jmunsch/.local/lib/python3.6/site-packages/.libs_cffi_backend/libffi-d78936b1.so.6.0.4" $LIBD
cp "/lib/x86_64-linux-gnu/libbz2.so.1.0" $LIBD
cp "/lib/x86_64-linux-gnu/libc.so.6" $LIBD
cp "/lib/x86_64-linux-gnu/libdl.so.2" $LIBD
cp "/lib/x86_64-linux-gnu/libexpat.so.1" $LIBD
cp "/lib/x86_64-linux-gnu/libgcc_s.so.1" $LIBD
cp "/lib/x86_64-linux-gnu/liblzma.so.5" $LIBD
cp "/lib/x86_64-linux-gnu/libm.so.6" $LIBD
cp "/lib/x86_64-linux-gnu/libnss_dns.so.2" $LIBD
cp "/lib/x86_64-linux-gnu/libnss_files.so.2" $LIBD
cp "/lib/x86_64-linux-gnu/libnss_mdns4_minimal.so.2" $LIBD
cp "/lib/x86_64-linux-gnu/libpthread.so.0" $LIBD
cp "/lib/x86_64-linux-gnu/libresolv.so.2" $LIBD
cp "/lib/x86_64-linux-gnu/librt.so.1" $LIBD
cp "/lib/x86_64-linux-gnu/libtinfo.so.5" $LIBD
cp "/lib/x86_64-linux-gnu/libudev.so.1" $LIBD
cp "/lib/x86_64-linux-gnu/libutil.so.1" $LIBD
cp "/lib/x86_64-linux-gnu/libuuid.so.1" $LIBD
cp "/lib/x86_64-linux-gnu/libz.so.1" $LIBD
cp "/usr/lib/x86_64-linux-gnu/libapt-pkg.so.5.0" $LIBD
cp "/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1" $LIBD
cp "/usr/lib/x86_64-linux-gnu/libffi.so.6" $LIBD
cp "/usr/lib/x86_64-linux-gnu/liblz4.so.1" $LIBD
cp "/usr/lib/x86_64-linux-gnu/libmpdec.so.2" $LIBD
cp "/usr/lib/x86_64-linux-gnu/libssl.so.1.1" $LIBD
cp "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" $LIBD
cp "/usr/lib/x86_64-linux-gnu/libzstd.so.1" $LIBD

zip -r $Z $LIBD

AWS_ACCESS_KEY_ID = "xxx" AWS_SECRET_ACCESS_KEY = "xxx" AWS_DEFAULT_REGION = "us-east-1" aws lambda update-function-code --function-name ok-today --zip-file fileb://ok-daily-lambda.zip

Вот структура каталогов самого последнего zip-файла:

Связанный:

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
11
0
8 059
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Существуют модули, которые нельзя добавить непосредственно в каталог site-packages, чтобы они распознавались в среде AWS Lambda. Когда это произойдет, вы должны получить образ Amazon Linux из репозиториев Docker и создать собственную скомпилированную среду в версии контейнера, которая будет работать на AWS Lambda.

Например, если вы хотите использовать Python 3.6, хорошим выбором будет amazonlinux:2018.03, если вы хотите установить больше пакетов, например. панды, numpy, scipy

    docker run -v $(pwd):/outputs -it amazonlinux:2018.03

Поскольку Amazon Linux основан на Red Hat, вам необходимо установить через yum все зависимости при запуске докера и уже созданной виртуальной среде.

    yum update -y
    yum install -y \
      python36 \
      python36-devel \
      python36-virtualenv \
      python34-setuptools \
      gcc \
      gcc-c++ \
      findutils \
      rsync \
      Cython \
      findutils \
      which \
      gzip \
      tar \
      man-pages \
      man \
      wget \
      make \
      zip

Для lxml вам также понадобится

    (lambda_docker) bash-4.2# yum install libxml2
    ...
    (lambda_docker) bash-4.2# yum install libxslt
    ...

Вы устанавливаете модуль как обычно

    pip3.6 install lxml

Вы должны увидеть что-то вроде

    (lambda_docker) bash-4.2# pip3.6 install lxml
    Collecting lxml
      Downloading https://files.pythonhosted.org/packages/2d/53/34a9f0c79c548e430148837892b6ae91adee571a0e8b6c17bd7ff9c2d12e/lxml-4.3.4-cp36-cp36m-manylinux1_x86_64.whl (5.7MB)
         |################################| 5.7MB 2.0MB/s 
    Installing collected packages: lxml

Затем создайте свою функцию lambda_function.py и добавьте ее в заархивированный пакет pushd-ed и popd-ed из вашего сеанса докера.

    from lxml import etree

    def lambda_handler(event, context):
        print(__name__)
        print(etree.LXML_VERSION)

После создания

    zip -g site-packages.zip lambda_function.py

Перед загрузкой вы можете убедиться, что ваш zip-файл содержит каталоги lxml

    [jonathan@docker lambda_docker]$ unzip -l site-packages.zip 
    Archive:  site-packages.zip
      Length      Date    Time    Name
    ---------  ---------- -----   ----
            0  06-29-2019 23:09   __pycache__/
          277  06-29-2019 23:09   __pycache__/easy_install.cpython-36.pyc
          126  06-29-2019 23:09   easy_install.py
          119  06-29-2019 23:29   lambda_function.py
            0  06-29-2019 23:21   lib/
            0  06-29-2019 23:39   lxml/
            0  06-29-2019 23:37   lxml-4.3.4.dist-info/
            4  06-29-2019 23:37   lxml-4.3.4.dist-info/INSTALLER
         2954  06-29-2019 23:37   lxml-4.3.4.dist-info/METADATA
        13384  06-29-2019 23:37   lxml-4.3.4.dist-info/RECORD
          109  06-29-2019 23:37   lxml-4.3.4.dist-info/WHEEL
            5  06-29-2019 23:37   lxml-4.3.4.dist-info/top_level.txt
         7668  06-29-2019 23:37   lxml/ElementInclude.py
          551  06-29-2019 23:37   lxml/__init__.py
            0  06-29-2019 23:37   lxml/__pycache__/
         3331  06-29-2019 23:37   lxml/__pycache__/ElementInclude.cpython-36.pyc
    ...

Теперь загрузите zip и создайте пустой тест {} в вашей лямбда-функции.

Результат

    START RequestId: bb240a17-c2dd-4d63-92c8-fa7561c09f64 Version: $LATEST
    lambda_function
    (4, 3, 4, 0)
    END RequestId: bb240a17-c2dd-4d63-92c8-fa7561c09f64
    REPORT RequestId: bb240a17-c2dd-4d63-92c8-fa7561c09f64  Duration: 0.30 ms   Billed Duration: 100 ms     Memory Size: 128 MB Max Memory Used: 50 MB  

Если вы предпочитаете изображение

Полностью готов к работе с AWS Lambda

Надеюсь, поможет (:

Извиняюсь, не хотел ввести в заблуждение.

Raunaqss 04.02.2021 23:47

Я столкнулся с похожей проблемой, и я нашел один быстрый обходной путь

Using pre-compiled build of lxml

Скачать https://github.com/shubh2502/aws-лямбда-lxml

  1. Папки 3.6.4 и 3.8.0 являются версиями lxml.
  2. Внутри lxml есть две сборки python27 и python36.

  3. В соответствии с версией AWS Lambda python выберите любой из них.

  4. Внутри python27 и python36 есть папка lxml

  5. Почтовый индекс с папкой lxml и убедитесь, что у python такая же версия

  6. В случае слоя AWS Lambda поместить в эту структуру папку lxml -

    python/lib/python3.6/сайт-пакеты

Я провел много времени в докере и разрабатывал эти вещи, этот метод был для меня спасением, я надеюсь, что это поможет вам

Я создавал zip как lambda.zip, не уверен, была ли проблема в lxml или в имени zip.

aniruddha 03.11.2020 19:09

Причина:

Файлы .so скомпилированы в другой ОС. (В моем случае macOS.)

Решение:

Очень помогла следующая статья:

Как создать слой Lambda, используя смоделированную среду Lambda с помощью Docker?

Все, что мне нужно было сделать, это:

cd /path_to_requirements_txt/

docker run -v "$PWD":/var/task "lambci/lambda:build-python3.7" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.7/site-packages/; exit"

Он создал python/lib/python3.7/site-packages/ со всеми зависимостями!

Если вы используете SERVERLESS для развертывания:

Затем проверьте версию Python в вашей локальной среде, а также версию среды выполнения lambda, которую вы используете.

Я использовал Python 3.8 на своем локальном компьютере, а версия среды выполнения лямбда использовала Python 3.7. Поэтому я изменил версию лямбда, чтобы использовать Python 3.8.

ЭТО РАБОТАЛО ДЛЯ МЕНЯ!!!

Я надеюсь, что это поможет вам

Другие вопросы по теме