Getting PIL/Pillow 4.2.1 to upload properly to AWS Lambda Py3.6

Basically, you have to compile the libraries (eg, PIL) either using Docker or, even better, an EC2 instance.

  1. Launch an Docker container like this: docker run --rm -it -v "%cd%:/code" lambci/lambda:build-python3.6 sh

  2. Inside there, navigate to the /code dir (cd /code), create a virtualenv (virtualenv env), activate it (source env/bin/activate) and finally, install your library (pip install pillow).

  3. Once you have installed your library, you can exit the container. The secret here is to move your package library to the root folder (where your main .py file is). For example, move the folder env/lib/python3.6/site-packages/PIL to the root.

Then, zip your PIL folder together with your .py file and you're set!

Full Example:

The following example compiles and compresses PIL and other common Python libraries to run in AWS Lambda.

Dockerfile:

FROM lambci/lambda:build-python3.6
WORKDIR /code
CMD ["sh", "entrypoint.sh"]

entrypoint.sh:

#!/bin/sh

set -ex

cd /code/

if [ ! -d "PIL" ]; then
    # Create virtual env, activate it and install PIL
    virtualenv env && source env/bin/activate && pip install pillow requests

    # Copy necessary files to the root folder
    rm -f build-output.zip
    #mkdir PIL
    cp -f -r env/lib/python3.6/site-packages/PIL .
    cp -f -r env/lib/python3.6/site-packages/requests .
    
    # below are the dependencies for the requests pkg
    cp -f -r env/lib/python3.6/site-packages/urllib3 .
    cp -f -r env/lib/python3.6/site-packages/certifi .
    cp -f -r env/lib/python3.6/site-packages/chardet .
    cp -f -r env/lib/python3.6/site-packages/idna .
    
    # Remove temp files
    rm -r env
fi

# ZIP it
zip -9 build-output *.py 
zip -9 -r build-output PIL
zip -9 -r build-output requests
zip -9 -r build-output urllib3
zip -9 -r build-output certifi
zip -9 -r build-output chardet
zip -9 -r build-output idna

To build (Windows):

docker build -t build_lambda .
docker run --rm -v "%cd%:/code" build_lambda

You can use a precompiled version of the PIL available here: https://github.com/Miserlou/lambda-packages

Just extract PIL folder to the deployment package and it should work.