15

app structure:

.
├── Makefile
├── Pipfile
├── Pipfile.lock
├── README.md
├── template.yaml
├── tests
│   ├── __init__.py
│   └── unit
│       └── lambda_application
│           ├── test_handler.py
│           └── test_parent_child_class.py
└── lambda_application
    ├── __init__.py
    ├── first_child_class.py
    ├── lambda_function.py
    ├── second_child_class.py
    ├── requirements.txt
    └── parent_class.py

4 directories, 14 files

Code sample from lambda_function.py:

import os
import json
from hashlib import sha256
import boto3
from requests import Session
from .first_child_class import FirstChildClass


def lambda_handler(event, context):
    # Do some stuff.

As is, I get the error message

Unable to import module 'lambda_function'

but If I comment out the last import, from .first_child_class import FirstChildClass, it is able to get past that part and get the error that I haven't loaded the module for that class.

I only seem to get this error when I run it in the lambci/lambda:python3.7 docker image and when I deploy on AWS. All my tests pass and it is able to import the module with no problems.

Is there something I should load/setup in the __init__.py file?

EDIT I changed the names of some of the files to post it here.

1 Answer 1

21

You are using a relative import here which works in case the code you are executing is in a module. However, since your code is being executed not as a module, your AWS Lambda fails.

https://stackoverflow.com/a/73149/6391078

A quick run locally gave the following error:

PYTHON 3.6

Traceback (most recent call last):
  File "lambda_function.py", line 4, in <module>
    from .first_child_class import FirstChildClass
ModuleNotFoundError: No module named '__main__.first_child_class'; '__main__' is not a package

Your tests pass because your testing suite imports the file as a module from the lambda_application folder which gets treated as a package in the testing module


This got me going in the correct direction but didn't quite give me the answer but did lead me to the answer, so I thought I would update what I found here.

I didn't try it but from what I found, I believe that:

from first_child_class import FirstChildClass

would be the simplest resolution.

What I ended up doing was moving the classes into a sub-directory and essentially did the same as above but with a package name prepended.

So, the file structure changed to:

.
├── Makefile
├── Pipfile
├── Pipfile.lock
├── README.md
├── template.yaml
├── tests
│   ├── __init__.py
│   └── unit
│       └── lambda_application
│           ├── test_handler.py
│           └── test_parent_child_class.py
└── lambda_application
    ├── __init__.py
    └── lib
        ├── first_child_class.py
        ├── second_child_class.py
        └── parent_class.py
    ├── lambda_function.py
    └── requirements.txt

and my import became from lib.first_child_class import FirstChildClass

Sign up to request clarification or add additional context in comments.

2 Comments

That makes a more sense now. I am just now sure how I need to fix it.
If the answer solves your problem, please consider marking it as correct answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.