11

I currently try to get this AWS Lambda Getting started tutorial running: https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example-deployment-pkg.html#with-s3-example-deployment-pkg-python

However, I always receive an error:

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

Log output

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  

I went that far to build my .zip from a lambci/docker-lambda image. But it didn't resolve my problem.

Here what's inside my .zip. Do you have any ideas, why I still get this error?

enter image description here

Stéphane Bruckert
  • 21,706
  • 14
  • 92
  • 130
Joey Coder
  • 3,199
  • 8
  • 28
  • 60
  • Did you have any luck? I am facing the same error – hax Nov 28 '19 at 07:13
  • @hax see my answer below. – Joey Coder Nov 28 '19 at 08:39
  • I posted a solution here that does not require Docker. You just create a layer, the trick being that you have the correct version of Python locally, which you can install if needed. https://stackoverflow.com/a/74736780/1375627 – MattC Dec 08 '22 at 22:00

5 Answers5

14

Using python 3.6 instead of 3.7 would just give me a different error. It seems AWS lambda is missing some components due to the way it was built.

5-minutes solution that worked for me:

Save all and it should just work! However you will have to make sure that redeploying the lambda keeps the layer somehow.


Full credits to this life saving blog post https://medium.com/@derekurizar/aws-lambda-python-pil-cannot-import-name-imaging-11b2377d31c4

Stéphane Bruckert
  • 21,706
  • 14
  • 92
  • 130
  • 2
    While I don't love relying on external sources maintained by someone else for production deployments, this saved my life. +1! – Alexander George Jul 27 '21 at 00:46
  • 1
    Dont forget to remove `Pillow` from your `requirements.txt` . Otherwise the arn is overridden and you keep getting the same error – Shubham Kumar Dec 27 '21 at 11:04
4

I was still facing the error despite trying all these steps. Finally I was able to find my issue :)

For me the Python version in AWS Lamda runtime was python 3.7.7. I installed Pillow using python 3.6. There seems to be some issue with compatibility of PIL with differnt versions of python.

So to resolve the issue either change AWS lambda runtime to python3.6.( This is what I tried and did work)

Alternatively one could also try installing pillow for python 3.7.7 and copying this to lambda.

As there are issues with cython the preferrable way would be to install packages in EC2 with amazon linux or using a AWS AMI docker image.

ArunJose
  • 1,999
  • 1
  • 10
  • 33
3

This is because PIL contains compiled binaries (cython) with your pip install and lambda doesn't know how to handle it.

Instead of creating a lambda function with docker and adding all unnecessary overhead, you can simply creating a zip file by using the following method:

  1. Download the "module-name"-"version"-cp"python-version"-cp"python-versionm-manylinux1_x86_64.whl file from pypi.org. Note: In your case, it should be Pillow-7.1.2-cp37-cp37m-manylinux1_x86_64.whl
  2. Unzip your whl file, by running unzip Pillow-7.1.2-cp37-cp37m-manylinux1_x86_64.whl
  3. Adding all the files along with your lambda_function.py into a new zip file
  4. Upload your new zip file to lambda and you're good to go.

This solution works well for any packages contain compiled binaries (cython) such as numpy.

Reference: https://aws.amazon.com/premiumsupport/knowledge-center/lambda-python-package-compatible

Ken Hui
  • 31
  • 3
2

To answer @hax comment, I ended up with this solution here: https://github.com/marcmetz/Create-AWS-Lambda-Function-with-Docker

The problem I faced was a different Python installation on my Mac than required on AWS. In order to use my solution install Docker, cd in the repository and add your packages to requirements.txt. Then simply run the following command:

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

That will (1) create a Docker container based on this, (2) Installs all your packages and dependencies defined in the requirements.txt and then (3) gives you back a .zip file in the repository folder. That .zip file can be used for your Lambda Function.

Make sure to also adjust lambda_function.py to whatever function you want there.

Joey Coder
  • 3,199
  • 8
  • 28
  • 60
  • In the second learning cycle have a look into layers for AWS Functions. A similar approach, just that you can write your lambda function in the editor which makes it more convenient. But for the beginning, the solution above should work. – Joey Coder Nov 28 '19 at 09:06
2

Some libraries like Pillow are deprecated and they are forked for the community to still upgrading them. The problem is the os base that runs python in aws, because they do not use forked libraries. For that, aws creates layers (not only for that but I will not explain that now) for lambdas and you can create one with your own resources on a specific os and specific version of your programming language ( in this case python) and put layers into your lambda and so you can run Pillow or another libraries with the same problem.

To create layers you need knowledge of docker and scripts for linux...

but why we will create water with sugar if it already exist?

In this repository: https://github.com/keithrozario/Klayers you have a lot of layer that you can use.

I give you an example of how add one layer when you have a problem with Pillow.

In this lambda I need to use PIL because I use aws Recognition text and I manage Image object to draw squares and other things. If you see I have the same error:

(I can't post images :( so here is the link) https://i.stack.imgur.com/pmptW.jpg

The next we need to do is erase the libraries, because we don't need that in the base code of the lambda for the reasons I was explained in the start of this article.

Your lambda now need to seem like that:

https://i.stack.imgur.com/rMGhk.jpg

Now, depend of your python version or your region in aws you will search in the repository the specific arn of the layer that you will need to use [https://github.com/keithrozario/Klayers/blob/master/deployments/python3.8/arns/us-east-1.csv]. In my case is python 3.8 and us-east-1 region.

https://i.stack.imgur.com/qHXJX.jpg

In this case the arn is : arn:aws:lambda:us-east-1:770693421928:layer:Klayers-python38Pillow:5

Go to your lambda to this part and click on layers: https://i.stack.imgur.com/O5Ejg.jpg

You will see this:

https://i.stack.imgur.com/RRRPE.jpg

Click in add layer-> Specified arn -> paste the arn

https://i.stack.imgur.com/Up6ek.jpg

And that's all, now your lambda function will run fine.

(deploy and test)

https://i.stack.imgur.com/rMGhk.jpg

yudhiesh
  • 6,383
  • 3
  • 16
  • 49