I am developing a microservice to analyze an image uploaded to an S3 AWS Bucket. I am using Serverless framework. I am using virtualenv to install the dependencies with PIP and serverless-python-requirements plugin to deploy these dependencies to the Lambda function.
However I am having an error when I deploy the microservice because of a missing .so file. The error I get is
Unable to import module 'handlers.image': libgthread-2.0.so.0: cannot open shared object file: No such file
My serverless.yml file is
service: sls-covid
provider:
name: aws
runtime: python3.8
profile: testuser
stage: ${opt:stage, 'staging'}
environment: ${file(environment.yml):${self:provider.stage}}
region: ${self:provider.environment.REGION}
iamRoleStatements:
# para poder leer y escribir en el bucket
- Effect: "Allow"
Action:
- "s3:*"
Resource: "*"
custom:
pythonRequirements:
dockerizePip: non-linux
package:
individually: true
exclude:
- node_modules/**
- env/**
- package.json
- package-lock.json
functions:
analyzeImage:
# para analizar la imagen cuando se almacena en S3
handler: handlers.image.analyze
events:
- s3:
bucket: ${self:service}-${self:provider.stage}-images
event: s3:ObjectCreated:*
rules:
- prefix: uploads/
plugins:
- serverless-python-requirements
The relevant code is:
import json
import logging
import boto3
from pydicom import dcmread
import numpy as np
# here the code stops working
import cv2
from pydicom.filebase import DicomBytesIO
logger = logging.getLogger()
logger.setLevel(logging.INFO)
s3 = boto3.client('s3')
def analyze(event, context):
print("=== event: ", event)
# code to read uploaded image from bucket and create a ds object
# code below is never executed since the error appears when the cv2 library is loaded
img = cv2.resize(ds.pixel_array, (224, 224))
And my requirements.txt contents is as follows:
numpy==1.18.4
opencv-python==4.2.0.34
pandas==1.0.3
pydicom==1.4.2
python-dateutil==2.8.1
pytz==2018.7
six==1.14.0
My question is. How can I properly upload opencv dependencies to my lambda function using the plugin? Should I do this in another way?
Thanks!