Reputation: 3489
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?
Upvotes: 12
Views: 21778
Reputation: 1
The error cannot import name '_imaging' from 'PIL'
typically occurs when the Pillow (PIL) library isn't properly compiled for the environment where it's meant to be running. AWS Lambda uses Amazon Linux 2023 for python3.12
and Amazon Linux 2 for other python versions (Lambda Runtimes), which may be different from your local development environment.
To resolve this, you need to inclide a version of Pillow that is compatible with AWS Lambda in your deployment package. Here is how you can do it:
pip install --target <YOUR_PACKAGE_DIR> pillow --platform manylinux2014_x86_64 --only-binary=:all: --upgrade
This command does the following:
<YOUR_PACKAGE_DIR>
directory (adjust as needed)manylinux2014_x86_64
platform, which is compatible with AWS Lambda<YOUR_PACKAGE_DIR>
directory in your Lambda deployment .zip file along with your function code.Upvotes: 0
Reputation: 3814
Providing an answer for people like me, where none of the answers above worked, since I wasn't even using PIL/Pillow:
To set the context, some libraries are automatically added as runtime-included dependencies, such as, for example boto3
. So you can just import
and run such libraries with the convenience that AWS will handle it for you.
In my case, I was using boto3
and jira
, only those 2. So I wrongly assumed that boto3
will be provided as a runtime dependency and I only have to package jira
as an explicit dependency.
However, after reading the docs more carefully about how this works, it turns out that "...dependencies in your deployment package or layers take precedence over runtime-included libraries, this can cause version misalignment problems...".
This effectively means that you cannot have both explicit and runtime-included dependency mix, since whatever you package will have precedence.
So make sure you keep this in mind and package all the dependencies explicitly!
Hope this helps
Upvotes: 0
Reputation: 22883
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:
look for your python version in https://github.com/keithrozario/Klayers/tree/master/deployments
open the HTML file for the region your lambda runs into
get the ARN for the latest Pillow version
on your Lambda in the AWS console, click "Layers (0)"
add a new layer:
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
Upvotes: 22
Reputation: 27
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.sstatic.net/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.sstatic.net/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.sstatic.net/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.sstatic.net/O5Ejg.jpg
You will see this:
https://i.sstatic.net/RRRPE.jpg
Click in add layer-> Specified arn -> paste the arn
https://i.sstatic.net/Up6ek.jpg
And that's all, now your lambda function will run fine.
(deploy and test)
https://i.sstatic.net/rMGhk.jpg
Upvotes: 1
Reputation: 2159
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.
Upvotes: 5
Reputation: 71
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:
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
Upvotes: 7
Reputation: 3489
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.
Upvotes: 2