首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在aws lambda上导入lxml etree

问无法在aws lambda上导入lxml etree
EN

Stack Overflow用户
提问于 2019-06-29 15:07:42
回答 4查看 11K关注 0票数 12
代码语言:javascript
复制
{
  "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

代码语言:javascript
复制
{
  "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,并尝试使用ec2实例上的"Amazon“映像来构建包。

我也尝试过,而在激活的静脉中:

代码语言:javascript
复制
STATIC_DEPS=true pip3 install lxml --target ./package --upgrade --no-cache-dir

我还尝试根据使用strace运行脚本时打开哪些文件来复制共享对象文件。

代码语言:javascript
复制
#! /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文件的目录结构:

相关信息:

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-06-29 21:51:59

有些模块不能直接添加到site-packages目录中,以便在AWS环境中识别。当发生这种情况时,您必须从Docker存储库获取Amazon映像,并在将运行在AWS Lambda上的容器版本中创建自己的编译环境。

例如,如果您想使用Python3.6,一个很好的选择是amazonlinux:2018.03,以防您想要安装更多的软件包,例如熊猫、numpy、scipy

代码语言:javascript
复制
    docker run -v $(pwd):/outputs -it amazonlinux:2018.03

由于Amazon是基于Red的,所以在运行docker并已经创建了虚拟环境时,必须通过yum安装所有依赖项。

代码语言:javascript
复制
    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,您还需要

代码语言:javascript
复制
    (lambda_docker) bash-4.2# yum install libxml2
    ...
    (lambda_docker) bash-4.2# yum install libxslt
    ...

您将一如既往地安装模块。

代码语言:javascript
复制
    pip3.6 install lxml

你应该看看

代码语言:javascript
复制
    (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和popd-ed中。

代码语言:javascript
复制
    from lxml import etree

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

创建后

代码语言:javascript
复制
    zip -g site-packages.zip lambda_function.py

上传之前,您可以检查zip文件是否包含lxml目录。

代码语言:javascript
复制
    [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并在lambda函数中创建一个空的测试{}。

结果

代码语言:javascript
复制
    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做好了准备

希望它有帮助(:

票数 7
EN

Stack Overflow用户

发布于 2020-05-14 05:56:32

我遇到了一个类似的问题,我想出了一个快速的解决办法。

使用预先编译的lxml构建。

下载https://github.com/shubh2502/aws-lambda-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层将lxml文件夹放入此结构- python/lib/python3.6/site-包

我花了很多时间在码头和建造这些东西,这个方法是我的救世主,我希望这能帮到你。

票数 10
EN

Stack Overflow用户

发布于 2021-02-01 13:06:51

原因:

在不同的操作系统上编译的.so文件。(就我而言,是macOS。)

解决方案:

以下这篇文章非常有用:

如何使用带有Docker的模拟Lambda环境创建Lambda层?

我要做的就是:

代码语言:javascript
复制
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/!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56818579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档