AWS error from Python: No module named lambda_function

Question:

I am creating a AWS Lambda python deployment package. I am using one external dependency requests. I installed the external dependency using the AWS documentation. Below is my Python code.

import requests

print('Loading function')

s3 = boto3.client('s3')


def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        s3.download_file(bucket,key, '/tmp/data.txt')
        lines = [line.rstrip('n') for line in open('/tmp/data.txt')]
        for line in lines:
            col=line.split(',')
            print(col[5],col[6])
        print("CONTENT TYPE: " + response['ContentType'])
        return response['ContentType']
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e

Created the Zip the content of the project-dir directory and uploaded to the lambda(Zip the directory content, not the directory). When I am execute the function I am getting the below mentioned error.

START RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058 Version: $LATEST
**Unable to import module 'lambda_function': No module named lambda_function**

END RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058
REPORT RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058  Duration: 19.63 ms  Billed Duration: 100 ms     Memory Size: 128 MB Max Memory Used: 9 MB
Asked By: Nithin

||

Answers:

Error was due to file name of the lambda function. While creating the lambda function it will ask for Lambda function handler. You have to name it Python_File_Name.Method_Name. In this scenario, I named it lambda.lambda_handler (lambda.py is the file name).

Please find below the snapshot.
enter image description here

Answered By: Nithin

I found Nithin’s answer very helpful. Here is a specific walk-through:

Look-up these values:

  1. The name of the lambda_handler function in your python script. The
    name used in the AWS examples is lambda_handler looking
    like def lambda_handler(event, context). In this case, the value is
    lambda_handler
  2. In the Lambda dashboard, find the name of the Handler in the Handler text-box in the Configuration section in the lambda dashboard for
    the function (shown in Nithin’s screenshot). My default name was
    lambda_function.lambda_handler.
  3. The name of your python script. Let’s say it’s cool.py

With these values, you would need to rename the handler (shown in the screenshot) to cool.lambda_handler. This is one way to get rid of the "Unable to import module lambda_function" errorMessage. If you were to rename the handler in your python script to sup then you’d need to rename the handler in the lambda dashboard to cool.sup

Answered By: user3303554

Another source of this problem is the permissions on the file that is zipped. It MUST be at least world-wide readable. (min chmod 444)

I ran the following on the python file before zipping it and it worked fine.

chmod u=rwx,go=r
Answered By: Catalin Ciurea

There are just so many gotchas when creating deployment packages for AWS Lambda (for Python). I have spent hours and hours on debugging sessions until I found a formula that rarely fails.

I have created a script that automates the entire process and therefore makes it less error prone. I have also wrote tutorial that explains how everything works. You may want to check it out:

Hassle-Free Python Lambda Deployment [Tutorial + Script]

Answered By: joarleymoraes

If you are uploading a zip file. Make sure that you are zipping the contents of the directory and not the directory itself.

Answered By: 2ank3th

I found this hard way after trying all of the solutions above. If you’re using sub-directories in the zip file, ensure you include the __init__.py file in each of the sub-directories and that worked for me.

Answered By: KApuri

I had the error too.
Turn out that my zip file include the code parent folder. When I unzip and inspect the zip file, the lambda_function file is under parent folder ./lambda.

Use the zip command, fix the error:

zip -r ../lambda.zip ./*
Answered By: Joe

I ran into the same issue, this was an exercise as part of a tutorial on lynda.com if I’m not wrong.
The mistake I made was not selecting the runtime as Python 3.6 which is an option in the lamda function console.

Answered By: Nadeem

You need to zip all the requirements, use this script

#!/usr/bin/env bash
rm package.zip
mkdir package
pip install -r requirements.txt --target package
cat $1 > package/lambda_function.py
cd package
zip -r9 "../package.zip" .
cd ..
rm -rf package

use with:

package.sh <python_file>
Answered By: Uri Goren

@nithin,
AWS released layers concept inside Lambda functions. You can create your layer and there you can upload as much as libraries and then you can connect the layer with the lambda functions.
For more details: https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html

Answered By: muTheTechie

In lambda_handler the format must be lambda_filename.lambda_functionName.
Supposing you want to run the lambda_handler function and it’s in lambda_function.py, then your handler format is lambda_function.lambda_handler.

Another reason for getting this error is module dependencies.

Your lambda_function.py must be in the root directory of the zip file.

Answered By: Primit

A perspective from 2019:

AWS Lambda now supports Python 3.7, which many people (including myself) choose to use as the runtime for inline lambdas.

Then I had to import an external dependency and I followed AWS Docs as the OP referred to. (local install –> zip –> upload).

I had the import module error and I realised my local PC had Python 2.7 as the default Python. When I invoked pip, it installed my dependency for Python 2.7.

So I switched locally to the Python version that matches the selected runtime version in the lambda console and then re-installed the external dependencies. This solved the problem for me. E.g.:

$ python3 -m pip install --target path/to/lambda_file <external_dependency_name>
Answered By: l001d

Here’s a quick step through.

Assume you have a folder called deploy, with your lambda file inside call lambda_function.py. Let’s assume this file looks something like this. (p1 and p2 represent third-party packages.)

import p1
import p2

def lambda_handler(event, context):
    # more code here

    return {
        "status": 200,
        "body" : "Hello from Lambda!",
    }

For every third-party dependency, you need to pip install <third-party-package> --target . from within the deploy folder.

pip install p1 --target .
pip install p2 --target .

Once you’ve done this, here’s what your structure should look like.

deploy/
├── lambda_function.py
├── p1/
│   ├── __init__.py
│   ├── a.py
│   ├── b.py
│   └── c.py
└── p2/
    ├── __init__.py
    ├── x.py
    ├── y.py
    └── z.py

Finally, you need to zip all the contents within the deploy folder to a compressed file. On a Mac or Linux, the command would look like zip -r ../deploy.zip * from within the deploy folder. Note that the -r flag is for recursive subfolders.

The structure of the file zip file should mirror the original folder.

deploy.zip/
├── lambda_function.py
├── p1/
│   ├── __init__.py
│   ├── a.py
│   ├── b.py
│   └── c.py
└── p2/
    ├── __init__.py
    ├── x.py
    ├── y.py
    └── z.py

Upload the zip file and specify the <file_name>.<function_name> for Lambda to enter into your process, such as lambda_function.lambda_handler for the example above.

Answered By: openwonk

Sharing my solution for the same issue, just in case it helps anyone.

Issue:
I got error: “[ERROR] Runtime.ImportModuleError: Unable to import module ‘lambda_function’: No module named ‘StringIO'” while executing aws-big-data-blog code[1] provided in AWS article[2].

Solution:
Changed Runtime from Python 3.7 to Python 2.7

[1] — https://github.com/bsnively/aws-big-data-blog/blob/master/aws-blog-vpcflowlogs-athena-quicksight/CloudwatchLogsToFirehose/lambdacode.py
[2] — https://aws.amazon.com/blogs/big-data/analyzing-vpc-flow-logs-with-amazon-kinesis-firehose-amazon-athena-and-amazon-quicksight/

Answered By: user72789

You can configure your Lambda function to pull in additional code and content in the form of layers. A layer is a ZIP archive that contains libraries, a custom runtime, or other dependencies. With layers, you can use libraries in your function without needing to include them in your deployment package. Layers let you keep your deployment package small, which makes development easier.

References:-

  1. https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html
  2. https://towardsdatascience.com/introduction-to-amazon-lambda-layers-and-boto3-using-python3-39bd390add17
Answered By: Rahul Satal

Make sure that you are zipping all dependencies in a folder structure as python/[Your All Dependencies] to make it work as per this documentation.

https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-path

Answered By: Sachin Kumar

My problem was that the .py file and dependencies were not in the zip’s “root” directory. e.g the path of libraries and lambda function .py must be:

<lambda_function_name>.py
<name of library>/foo/bar/

not

/foo/bar/<name of library>/foo2/bar2

For example:

drwxr-xr-x  3.0 unx        0 bx stor 20-Apr-17 19:43 boto3/ec2/__pycache__/
-rw-r--r--  3.0 unx      192 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/__init__.cpython-37.pyc
-rw-r--r--  3.0 unx      758 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/deletetags.cpython-37.pyc
-rw-r--r--  3.0 unx      965 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/createtags.cpython-37.pyc
-rw-r--r--  3.0 unx     7781 tx defN 20-Apr-17 20:33 download-cs-sensors-to-s3.py
Answered By: lobi

Please add below one after Import requests

import boto3

What I can see that is missing in your code.

Answered By: Mrinal

The issue here that the Python version used to build your Lambda function dependencies (on your own machine) is different than the selected Python version for your Lambda function. This case is common especially if the Numpy library part of your dependencies.

Example: Your machine’s python version: 3.6 —> Lambda python version 3.6

Answered By: Sharhabeel Hamdan

Your package directories in your zip must be world readable too.

To identify if this is your problem (Linux) use:

find $ZIP_SOURCE -type d -not -perm /001 -printf %M "%pn"

To fix use:

find $ZIP_SOURCE  -type d -not -perm /001 -exec chmod o+x {} ;

File readable is also a requirement. To identify if this is your problem use:

find $ZIP_SOURCE -type f -not -perm /004 -printf %M "%pn"

To fix use:

find $ZIP_SOURCE  -type f -not -perm /004 -exec chmod o+r {} ;

If you had this problem and you are working in Linux, check that umask is appropriately set when creating or checking out of git your python packages e.g. put this in you packaging script or .bashrc:

umask 0002 
Answered By: hi2meuk

change python file name to lambda_function.py, for example in my case the filename was app.py
the error gone once i change filename to lambda_function.py

Answered By: zaheer

TL;DR, try chmod 755 python

I know this is a very long thread already, but if you still can’t solve the following issue after reading all the potential solutions posted here by all the community members, you can try the solution that solved my problem.

{
  "errorMessage": "Unable to import module 'xxx': No module named 'yyy'",
  "errorType": "Runtime.ImportModuleError",
  "stackTrace": []
}

To be clear, I’m talking about the zip file for the AWS Lambda Layer (NOT the deployment package) for the Python runtime. In my case, all the dependencies are placed under a folder named python according to the doc.

AWS Lambda Include library dependencies in a layer

Note that using a folder named python is better than the other folder structure since it does not depend on the version of Python.

Then you should try doing an ls in Lambda using the following code snippet:

import os

def lambda_handler(event, context):
    print(os.listdir('/opt'))
    print(os.listdir('/opt/python'))

Here is the expected output:

['python']
['OpenSSL', '__pycache__', ... 'urllib3', 'urllib3-1.24.2.dist-info']

In my case, before the issue was solved, the output was

{
  "errorMessage": "[Errno 13] Permission denied: '/opt/python'",
  "errorType": "PermissionError",
  "stackTrace": [
    "  File "/var/task/lambda_function.py", line 16, in lambda_handlern    print(os.listdir('/opt/python'))n"
  ]
}

Therefore, it’s clearly a permission issue. After doing a chmod 755 python, zip -r9 lambda-layer python, and uploading lambda-layer.zip to Lambda, the issue is solved.

Answered By: jellycsc

I was building the lambda via a container, rather than a zip file.

What solved it in my case was to copy the project into the "${LAMBDA_TASK_ROOT}" folder, and not just a custom folder of my choosing.

FROM public.ecr.aws/lambda/python:3.8

WORKDIR ${LAMBDA_TASK_ROOT}
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD ["lambda_function.lambda_handler"]

Even though I previously set the WORKDIR, and even tried to use the "WORKDIR override" setting in Lambda, it only worked when I used the "${LAMBDA_TASK_ROOT}" folder.

Answered By: UriP

Adding this answer for anyone else coming to this question with the same issue and none of the other solutions are working for them. The same error will be observed if you’ve uploaded code to the lambda, and try to test it without clicking Deploy; you must deploy the lambda before being able to run the test.
enter image description here

Answered By: JMercer

Make sure your lambda function name and handler name matches. For eg:
if your lambda function name is ‘index.py‘ and you have given handler name as ‘lambda_function.lambda_handler‘ then you will get an error as ‘Unable to import module ‘lambda_function’: No module named ‘lambda_function‘.

Resolution:
you have to update the lambda_handler name from ‘lambda_function.lambda_handler‘ to ‘index.lambda_handler

Answered By: Harsh Wardhan Gupta

I am working on an AWS training course which goes through Lambda functions. It seems very basic, but you have to choose Deploy before test events will work – especially if you have uploaded code that did not contain the lambda_function.lambda_handler method – this was my mistake. This was not clear to me through my training, and thus lost 30+ minutes on this silly error.

Answered By: kirrer

Not sure if it was mentioned above, but .zip file name and the contents of the zip should match.
Ex: file: lambda.zip and the content: lambda.py

Answered By: MederD

Go to Lambda functions, then select Layers, then scroll to Runtime settings and click Edit.

enter image description here

You may also configure the SAM with the specific Handler in your YAML file. Example below.

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
  getRecommendation:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: pythonfilename.lambda_handler
      Runtime: python3.7
      CodeUri: .
      Description: ''
      MemorySize: 128
      Timeout: 3
      Role: 'arn:aws:iam::xxxxx:role/lambdaroleIam'
Answered By: rabkaman

This is because maybe your code contains some packages(eg. request module of python) that are unknown to the lambda function. To solve this, AWS introduced the layers concept inside Lambda functions, there you can upload as many as libraries, and then you can connect the layer with the lambda functions.

Answered By: sarvesh_r

I understand that I’m replying to an old thread, but in case someone else runs into this issue:

I had this same problem today deploying a Python Lambda function using CloudFormation from my M1 Mac. The filename and handler seemed correct, but the Lambda framework was still unable to find my module.

In the end it turns out that I was configuring the function to use the x86_64 architecture. Changing the CloudFormation template to use the arm64 architecture fixed the problem.

Answered By: Javi Lavandeira

One thing that took me some research to realize was that I had python3.10 locally and thus in the folder structure, and lambda only accepts up to python3.9. In my case, I could just change the name of the folder from python3.10 to python 3.9 (python/lib/python3.9/site-packages), but you should just make sure you’re using a version of python that is allowed by lambda.

Answered By: SomeDE

simple soluton

  1. create a zip of content for example I have a lambda function named as

    testfunction then the .zip will be zip -r testfunction.zip lambda_function.py other_conent.py

  2. deploy the changes after every change

Answered By: Sheikh Aafaq Rashid