How to install aws-wsgi and Flask in AWS Lambda?

162 views Asked by At

I pip installed aws-wsgi and flask using AWS Cloud9 and then downloaded the zip file.

This file was then uploaded to a Lambda Layer, which was then attached to my Lambda Function. However, I still get the following error:

{  
  "errorMessage": "Unable to import module 'lambda_function': No module named 'awsgi'",
  "errorType": "Runtime.ImportModuleError",
  "requestId": "81e04845-856a-4b98-85a4-7de4644e6244",
  "stackTrace": []
}

I also get similar error for flask.
This is weird because I've imported requests, psycopg2-binary and other dependencies the same way. Only these 2 (awsgi & flask) are throwing errors.
Is there a different way to install these dependencies?

EDIT

STEPS how I created the layer (working on Windows):

  1. Logged into AWS Cloud9
  2. installed get-pip.py with the curl command: curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
  3. python3 get-pip.py
  4. python3 -m pip install flask aws-wsgi -t .
  5. cd out of the directory named dependency
  6. zip -r dependencies.zip dependency/
  7. downloaded the zip file
  8. uploaded the zip file to Lambda Layers through AWS Lambda Console

Contents of the layer -> dependencies.zip

1

There are 1 answers

1
Quassnoi On BEST ANSWER

From the docs:

When you add a layer to a function, Lambda loads the layer content into the /opt directory of that execution environment. For each Lambda runtime, the PATH variable already includes specific folder paths within the /opt directory. To ensure that your layer content gets picked up by the PATH variable, include the content in the following folder paths:

Runtime Path
Python python
python/lib/python3.x/site-packages (site directories)

It means that you should have packaged your dependencies into a folder named python (and not dependency)

You can do that by doing this:

  1. Create a file named requirements.txt with the list of your dependencies

  2. 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 dependencies.zip python/
    

You don't have to do that on Cloud9. Any Python distribution (even Windows-based or Mac-based) will do.

The parameters mean:

  • --only-binary=:all:: don't compile any packages from source on the machine, only use binary distributions.
  • --platform manylinux2014_x86_64: use the binaries targeting glibc-based distributions for x86_64 according to the table. Replace manylinux2014_x86_64 with manylinux2014_aarch64 if you are going to use your layer with ARM Lambdas.
  • --target=python: put the dependencies into the subfolder python of the current folder (see above why)
  • --implementation cp: only install dependencies runnable by CPython. That's the implementation that runs python code on Lambda runtime.
  • --python-version 3.12: match the version of the runtime that will be running your lambdas.