Lambda image directory structure / imports

0

I'm deploying a lambda function as an image. Locally I have the following structure:


├── project_folder/
    ├── lambda_handler.py
    ├── utils/
        ├── function_1.py
        ├── function_2.py
    └── modules/
    ├── module_1.py
    ├── module_2.py

My dockerfile looks like this

FROM public.ecr.aws/lambda/python:3.11
COPY project_folder/ requirements.txt ./

RUN pip3 install -r requirements.txt

CMD ["lambda_handler.lambda_handler"]

In lambda_handler.py I'm doing:

from utils import function_1.py
module = importlib.import_module(module_name)

In the modules I'm doing:

from ..utils import function_2

In the function_1.py I'm doing:

import function_2

I can't for the life of me figure it out how the structure and imports should be. I tried multiple combinations folder structure and imports but I keep getting errors like:

[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_handler': No module named 'function_1' [ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_handler': attempted relative import beyond top-level package

With the imports I'm doing, how should the directory structure be and how to do the relative imports?

asked 11 days ago365 views
1 Answer
0

Hi.

I'm using handler for the entry point function name to avoid confusion in the example below.

This is my folder structure: Folders tree screenshot

Dockerfile:

FROM public.ecr.aws/lambda/python:3.11
COPY project_folder/ requirements.txt ./

RUN pip install -r requirements.txt

CMD ["lambda_handler.handler"]

project_folder/modules/__init__.py is empty. See Python packages documentation for more details why you will need it.

project_folder/modules/module1.py:

from utils.function_1 import get_python_version


def module_say_hello():
    return "I'm using " + get_python_version() + "!"

project_folder/utils/function_1.py:

import sys
def get_python_version():
    return 'Python' + sys.version + '!'

project_folder/lambda_handler.py:

from modules.module1 import module_say_hello

def handler(event, context):
    return module_say_hello()

template.yaml - SAM template for test deployment to an AWS account:

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31

Resources:
  PythonDockerImageFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      MemorySize: 2048
      Timeout: 900
    Metadata:
      DockerContext: ./
      Dockerfile: Dockerfile

Test invoke with AWS CLI: Output screenshot

Additional references:

Best regards,

AWS
answered 11 days ago
  • Hi Dmitry, thank you for the answer. Unfortunately, no. I have the correct def lambda_handler correctly defined. But in this scenario, if you add a second folder modules/ parallel to utils/ and import something from utils in modules/module_1.py, how would that look?

  • Updated response with multiple folders.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions