I'm facing an issue that os
does not have an add_dll_directory
attribute in the AWS lambda function on the trigger.
I have written code for creating a thumbnail of a video and I have tried it locally that's working fine but when I upload this function with the required libraries then I get this issue and still, I'm unable to resolve it. I did not get any help from the internet yet regarding this issue.
that is an issue that I'm facing
[ERROR] AttributeError: module 'os' has no attribute 'add_dll_directory'
Traceback (most recent call last):
File "/var/lang/lib/python3.12/importlib/__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1381, in _gcd_import
File "<frozen importlib._bootstrap>", line 1354, in _find_and_load
File "<frozen importlib._bootstrap>", line 1325, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 929, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 994, in exec_module
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "/var/task/lambda_function.py", line 2, in <module>
import cv2
File "/var/task/cv2/__init__.py", line 11, in <module>
import numpy
File "/var/task/numpy/__init__.py", line 112, in <module>
_delvewheel_patch_1_5_2()
File "/var/task/numpy/__init__.py", line 109, in _delvewheel_patch_1_5_2
os.add_dll_directory(libs_dir)
This is the code that I'm using for creating a thumbnail
import json
import cv2
import tempfile
from PIL import Image
from io import BytesIO
import boto3
s3 = boto3.client('s3')
def get_video_file(bucket, key):
video_file = s3.get_object(Bucket=bucket, Key=key)['Body'].read()
return video_file
def upload_image_file(image_byte_data, bucket, key):
s3.put_object(Bucket=bucket, Key=key, Body=image_byte_data, ContentType="image/png")
def generate_thumbnail(video_byte_data):
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as temp_file:
temp_file_path = temp_file.name
temp_file.write(video_byte_data)
video_capture = cv2.VideoCapture(temp_file_path, cv2.CAP_ANY)
success, frame = video_capture.read()
if success:
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
thumbnail_image = Image.fromarray(frame_rgb)
thumbnail_size = (320,320)
thumbnail_image.resize(thumbnail_size)
thumbnail_data = BytesIO()
thumbnail_image.save(thumbnail_data, format='PNG')
thumbnail_bytes = thumbnail_data.getvalue()
return thumbnail_bytes
else:
raise ValueError('Unable to read video frame')
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
video_file = get_video_file(bucket, key)
image_output_file = generate_thumbnail(video_file)
upload_image_file(image_output_file, "thumbnail876", key.split(".")[0]+".png")
return {
"statusCode": 200,
"body": json.dumps(
{
"message": "hello world",
}
),
}
Please can someone tell me why I'm facing this issue? and how can I resolve this? Thanks
Lambda runtime doesn't provide Pillow or openCV, and you seem to have packaged Windows binary distributions of your dependencies with your Lambda code.
You need to package the distributions compatible with Amazon Linux and the architecture of your Lambda function (x86_64 or arm).
The easiest way to do this is create a layer.
Put the list of your dependencies (Pillow, opencv-python-headless, plus whatever else you need) into requirements.txt
Run these commands:
pip install \
--platform manylinux2014_x86_64 \
--target=python \
--implementation cp \
--python-version 3.12 \
--only-binary=:all: \
--upgrade \
-r requirements.txt
zip -r imaging.zip python/
If your Lambda is running on ARM, replace manylinux2014_x86_64
with manylinux2014_aarch64
Create the layer from the resulting zip file and use it in your lambda.