Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python not finding module when running AWS sam local invoke

I have just started using AWS serverless using SAM and have run into the problem below:

SAM invoke can't seem to find a python module that my lambda handler is importing but I can otherwise import that module.

The structure of my project is:

root-dir/

  • mymodulename/
    • mymodule.py
  • aws/
    • sam/
      • template.yaml
      • packaged.yaml
      • myawsservice/
        • app.py
      • test/
        • test_event.json

I am working in a python3.6 virtual environment and I have installed my python package (mymodulename) using setup tool:

python setup.py develop

So if I do a pip freeze in my virtual environment I see:

Pillow==6.0.0
PyPDF2==1.26.0
reportlab==3.5.20
mymodulename==0.5.0

Also if I go:

cd root-dir/aws/sam/
python

>>> import mymodulename

This succeeds. So it is on the python path.

But when I invoke sam locally i.e.:

sam local invoke MyAWSServiceFunction --event ../sam/test/test_event.json

I get the error message:

2019-05-02 09:19:17 Found credentials in shared credentials file: ~/.aws/credentials
2019-05-02 09:19:18 Invoking app.lambda_handler (python3.6)

Fetching lambci/lambda:python3.6 Docker container image......
2019-05-02 09:19:19 Mounting /home/myname/root-dir/aws/sam/myawsservice as /var/task:ro,delegated inside runtime container
START RequestId: 245daefe-ecfb-4530-9d15-cf07f55e0f3d Version: $LATEST
Unable to import module 'app': No module named 'mymodulename'
END RequestId: 245daefe-ecfb-4530-9d15-cf07f55e0f3d
REPORT RequestId: 245daefe-ecfb-4530-9d15-cf07f55e0f3d Duration: 31 ms 
Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 19 MB

{"errorMessage": "Unable to import module 'app'"}

Here is the code for my app.py:

from mymodulename.mymodule import mymodulefunction

def lambda_handler(event, context):    
    return mymodulefunction(event['body'])

I can run the code above from my unit test just not from the sam invoke environment.

template.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: > something

Globals:
  Function:
    Timeout: 3

Resources:
  MyAWSServiceFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: myawsservice/
      Handler: app.lambda_handler
      Runtime: python3.6

Help appreciated.

EDIT:

One workaround is to put the app.py, requirements.txt and template.yaml in the root directory and do:

sam build

This will store the 3rd party dependencies and my own python module together and template.py will now be able to find it during sam local invoke.

This is however not practical for bigger projects, and I guess the answer for now might be something like this. Although this is for a serverless.yaml. I'm not sure if SAM supports this syntax. Guessing no.

like image 496
Willeman Avatar asked May 02 '19 08:05

Willeman


People also ask

How do I resolve the unable to import module error that I receive when I run Lambda code in Python?

This is because Lambda isn't prepackaged with all Python libraries. To resolve this error, create a deployment package or Lambda layer that includes the libraries that you want to use in your Python code for Lambda. Important: Make sure that you put the library that you import for Python inside the /python folder.

How do I run Lambda locally with Sam?

You can invoke your AWS Lambda function locally by using the sam local invoke AWS SAM CLI command and providing the function's logical ID and an event file. Alternatively, sam local invoke also accepts stdin as an event. For more information about events, see Event in the AWS Lambda Developer Guide.


1 Answers

It's being a long time since this question was opened, but it might help to someone. How I fixed it:

  • Move your code from mymodulename/ to mymodulename/mymodulename/__init__.py
  • In mymodulename create a setup.py who will be responsible to create a package called mymodulename
  • In your requirements.txt of your lambda function add this: -e mymodulename/

The -e references to your local code, this link might helps also.

like image 192
Lücks Avatar answered Nov 02 '22 14:11

Lücks