Adi shukla
Adi shukla

Reputation: 303

Unable to import modules from aws lambda layer

I have a requirements file for my pip packages. I installed it in a target folder and zipped the contents and uploaded it on AWS lambda layer.

Requirements.txt

asgiref==3.2.3
certifi==2019.11.28
chardet==3.0.4
cloudevents==0.2.4
decorator==4.4.1
Django==3.0
idna==2.8
jaeger-client==4.2.0
jsonpath-ng==1.4.3
pbr==5.4.4
ply==3.11
pytz==2019.3
requests==2.22.0
six==1.13.0
sqlparse==0.3.0
urllib3==1.25.7
aws-xray-sdk
mysql-connector-python
gunicorn

I used the command pip3 install -r requirements.txt -t python/ where python is the target directory. This image shows the content of python directory. enter image description here

After this I zipped the content of this directory and published it as a layer on aws lambda. I made a dummy lambda function to check if the layer is working or not.

import json
import django

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

The log file error :

Response:
{
  "errorMessage": "Unable to import module 'lambda_function'"
}

Request ID:
"66ce85e0-59f0-4e5c-98f9-6fa3e3eb17d0"

Function Logs:
START RequestId: 66ce85e0-59f0-4e5c-98f9-6fa3e3eb17d0 Version: $LATEST
Unable to import module 'lambda_function': No module named 'django'

END RequestId: 66ce85e0-59f0-4e5c-98f9-6fa3e3eb17d0
REPORT RequestId: 66ce85e0-59f0-4e5c-98f9-6fa3e3eb17d0  Duration: 0.64 ms   Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 42 MB  Init Duration: 1.81 ms  

Upvotes: 6

Views: 13965

Answers (3)

Jason
Jason

Reputation: 1094

Asked and answered, but if anybody else runs into this thread who is trying to bake their own Python layer, here's how I got set things up to work...

Directory structure for the .zip you submit as the Lambda layer (thanks Ryan Lutz for the reminder about the "python" directory):

python/
   fubar /
      __init.py__
      foo.py

__init.py__

from .foo import Foo

foo.py

class Foo:
   def bar(self):
      print("Fubar!")

In your Lambda function (with the layer added)...

from fubar import Foo

var foo = Foo()
print (foo.bar())

Upvotes: 3

Ryan Lutz
Ryan Lutz

Reputation: 555

You mention that you 'zipped the content of this directory' referring to the python folder. When you create a layer via a .zip package, python packages need to be in a 'python' folder subdirectory. They can not be all at the root of the zipped folder.

Upvotes: 6

Marcin
Marcin

Reputation: 238995

If layer would suite you, I can let you know that I just successful constructed a django layer based on your requirements.txt file which could be imported in lambda.

To build the layer I used lambci/lambda tool. To ease the process, I used the following snippet from here.

The layer had 42 MB which is close to the 50 MB limit of lambda.

If you don't want to use layer, you can also use the same docker tool to build regular deployment package as explained in the recent AWS blog:

Since layer works, including django in a regular package should also work.

Upvotes: 2

Related Questions