I am trying to create thumbnails for photos that are in my s3 bucket, using lambda function. I have added the lambda function code inside the code editor in lambda, and have separately compiled and packaged the pillow library using my local machine on macOS. it didn't work and error each time was the PIL cannot be found, I think it was because lambda OS requires Amazon linux.
Then, I spun an ec2 instance with Amazon linux 2 AMI, compiled and zipped the pillow library inside the ec2 instance.
Then downloaded the zipped file to my local machine. As a final step created a lambda layer, and uploaded the zipped file, and added the layer to my lambda function. This should have solved the issue, but it still didn't.
Error message after testing the lambda function:
Test Event Name test2
Response
{
"errorMessage": "Unable to import module 'lambda_function': No module named 'PIL'",
"errorType": "Runtime.ImportModuleError",
"requestId": "c817cf4b-ba94-4fda-bf39-fefce592d42e",
"stackTrace": []
}
Function Logs
START RequestId: c817cf4b-ba94-4fda-bf39-fefce592d42e Version: $LATEST
[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'PIL'
Traceback (most recent call last):END RequestId: c817cf4b-ba94-4fda-bf39-fefce592d42e
REPORT RequestId: c817cf4b-ba94-4fda-bf39-fefce592d42e Duration: 1.96 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 53 MB Init Duration: 261.59 ms
Lambda code:
import sys
import urllib.request
from PIL import Image
s3_client = boto3.client('s3')
def resize_image(image_path, resized_path):
with Image.open(image_path) as img:
img.thumbnail((500, 500))
img.save(resized_path)
def lambda_handler(event, context):
for record in event['Records']:
bucket = record['s3']['bucket']['name']
key = urllib.parse.unquote_plus(record['s3']['object']['key'], encoding='utf-8')
if "/raw-media/" not in key:
continue
tmpkey = key.replace('/', '')
download_path = '/tmp/{}{}'.format(uuid.uuid4(), tmpkey)
upload_path = '/tmp/resized-{}'.format(tmpkey)
s3_client.download_file(bucket, key, download_path)
resize_image(download_path, upload_path)
# Extract the username and replace "raw-media" with "thumbnails" for the upload
user_folder = key.split("/")[0] # get the username folder
thumbnail_key = f"{user_folder}/thumbnails/{tmpkey}"
s3_client.upload_file(upload_path, bucket, thumbnail_key)
Any suggestion please, how to solve this? I also have tried a lambda function for resizing photos, and I have got the same errors. I even tried docker, but each time there were errors.