AWS Lamda:无法从“ PIL”导入名称“ _imaging”

时间:2019-07-25 08:15:20

标签: python amazon-web-services aws-lambda

我目前正在尝试运行此AWS Lambda入门教程:https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example-deployment-pkg.html#with-s3-example-deployment-pkg-python

但是,我总是收到一个错误:

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

日志输出

START RequestId: fefba1d1-443c-4617-a5ad-c3aac19e5591 Version: $LATEST
[ERROR] Runtime.ImportModuleError: Unable to import module 'CreateThumbnail': cannot import name '_imaging' from 'PIL' (/var/task/PIL/__init__.py)
END RequestId: fefba1d1-443c-4617-a5ad-c3aac19e5591
REPORT RequestId: fefba1d1-443c-4617-a5ad-c3aac19e5591  Duration: 1.52 ms   Billed Duration: 100 ms     Memory Size: 1024 MB    Max Memory Used: 71 MB  

我走得很远,从lambci/docker-lambda映像构建.zip。但这并不能解决我的问题。

这是我的.zip文件中的内容。您有什么想法,为什么我仍然会收到此错误?

enter image description here

5 个答案:

答案 0 :(得分:2)

要回答@hax评论,我在这里得到了以下解决方案: https://github.com/marcmetz/Create-AWS-Lambda-Function-with-Docker

我遇到的问题是Mac上的Python安装与AWS上的安装不同。为了使用我的解决方案,请在存储库中安装cd Docker,并将您的软件包添加到requirements.txt。然后只需运行以下命令:

docker build -t fbprophet . && \
docker run --rm -v $PWD:/export \
fbprophet cp upload-to-s3.zip /export

这将(1)基于this创建一个Docker容器,(2)安装在requirements.txt中定义的所有软件包和依赖项,然后(3)在存储库中返回一个.zip文件。夹。该.zip文件可用于您的Lambda函数。

请确保还将lambda_function.py调整为所需的任何功能。

答案 1 :(得分:1)

尽管尝试了所有这些步骤,但我仍然遇到错误。终于我找到了我的问题:)

对我来说,AWS Lamda运行时中的Python版本是 python 3.7.7 。我使用 python 3.6安装了Pillow。 PIL与不同版本的python的兼容性似乎存在一些问题。

因此,要解决此问题,请将AWS lambda运行时更改为python3.6。(这是我尝试并做过的事情)

或者,也可以尝试为python 3.7.7安装枕头并将其复制到lambda。

由于cython存在问题,首选的方法是使用Amazon Linux在EC2中安装软件包或使用AWS AMI docker映像。

答案 2 :(得分:1)

不推荐使用Pillow之类的某些库,它们被分叉给社区,以便仍在升级它们。问题是在aws中运行python的os base,因为它们不使用派生库。为此,aws为lambda创建层(不仅为此,我现在也不会解释),并且您可以在特定的操作系统和特定版本的编程语言(在本例中为python)上使用自己的资源创建一个层,并放置层进入lambda,因此您可以运行Pillow或其他具有相同问题的库。

要创建层,您需要有关docker和Linux脚本的知识...

但是为什么我们要用糖来制造水呢?

在此存储库中:https://github.com/keithrozario/Klayers 您可以使用很多图层。

我举一个例子,说明当枕头出现问题时如何添加一层。

在此lambda中,我需要使用PIL,因为我使用了aws Recognition文本,并且我管理Image对象来绘制正方形和其他东西。如果看到我有相同的错误:

(我无法发布图片:(所以这里是链接) https://i.imgur.com/ifhv4pJ.jpg

接下来我们要做的是擦除库,因为出于本文开头所述的原因,我们不需要在lambda的基本代码中使用它。

您的lambda现在需要看起来像这样:

https://i.imgur.com/Y8hvqa0.jpg

现在,取决于您的python版本或aws中的区域,您将在存储库中搜索需要使用的图层的特定arn [https://github.com/keithrozario/Klayers/blob/master/部署/python3.8/arns/us-east-1.csv]。以我为例,是python 3.8和us-east-1地区。

https://i.imgur.com/RSjva28.jpg

在这种情况下,arn为: arn:aws:lambda:us-east-1:770693421928:layer:Klayers-python38枕头:5

转到此部分的lambda并单击图层: https://i.imgur.com/mTyPHWP.jpg

您将看到以下内容:

https://i.imgur.com/Iw8gNDa.jpg

单击添加层->指定的arn->粘贴arn

https://i.imgur.com/y8C7OmE.jpg

仅此而已,现在您的lambda函数将正常运行。

(部署和测试)

https://i.imgur.com/Y8hvqa0.jpg

答案 3 :(得分:1)

使用 python 3.6 而不是 3.7 只会给我一个不同的错误。由于构建方式的原因,AWS lambda 似乎缺少一些组件。

对我有用的 5 分钟解决方案:

保存所有,它应该可以正常工作!但是,您必须确保重新部署 lambda 以某种方式保留该层。


感谢这篇拯救生命的博文 https://medium.com/@derekurizar/aws-lambda-python-pil-cannot-import-name-imaging-11b2377d31c4

答案 4 :(得分:0)

这是因为PIL在您的pip安装中包含编译的二进制文件(cython),而lambda不知道如何处理。

您可以使用以下方法简单地创建一个zip文件,而不是使用docker创建lambda函数并添加所有不必要的开销:

  1. 从pypi.org下载“模块名称”-“版本” -cp“ python-版本” -cp” python-versionm-manylinux1_x86_64.whl文件。注意:在您的情况下,应为{{3} }
  2. 通过运行Pillow-7.1.2-cp37-cp37m-manylinux1_x86_64.whl的解压缩来解压缩您的whl文件
  3. 将所有文件以及lambda_function.py一起添加到新的zip文件中
  4. 将新的zip文件上传到lambda,您一切顺利。

此解决方案适用于任何包含已编译二进制文件(cython)的软件包,例如numpy。

参考: Pillow-7.1.2-cp37-cp37m-manylinux1_x86_64.whl