Search code examples
pythonamazon-web-servicesaws-lambdaserverless

AWS lambda python multiple files application can't import one from another


I have the following structure of my AWS lambda project:

module
  app.py
  b.py

app.py is my default aws lambda function with lambda_handler, it works fine. I decided to pull all the heavy calculations out of it to function calc of b.py.

Then, I imported it to app.py:

from module.b import calc

Now, when I run it locally with sam local invoke Function --event events/event.json, it raises an error:

{"errorType":"Runtime.ImportModuleError","errorMessage":"Unable to import module 'app': No module named 'module'"}

It seems to me that when it prepares the code to run, it moves the files to some other directory, so the imports break. To fix this, I tried to use relative import:

from .b import calc

But it also raised an error:

{"errorType":"Runtime.ImportModuleError","errorMessage":"Unable to import module 'app': attempted relative import with no known parent package"}

How do I setup a multi-file python application on aws lambda?


Solution

  • This is how me resolve that problem.

    First your root folder need to seem like this:

    lambda_folder
        lambda_function.py // Or your main.py.... this file have the method lambda_handler
    

    Now... When I use multiple files... I always use a lib folder. Like this:

    lambda_folder
        lib
            lib1.py
            lib2.py
            lib3.py
        lambda_function.py
    
    

    IMPORTANT

    Inside your lib folder you always need an __init__.py or you can't see the files inside.

    lambda_folder
        lib
            lib1.py
            lib2.py
            lib3.py
            __init__.py
        lambda_function.py
    

    NOTE: the __init__.py needs to have the two underscores before and after init.

    EXAMPLE

    lib1.py

    def sum(a,b):
        return a+b
    
    

    lambda_function.py

    from lib import lib1
    import json
    
    def lambda_handler(event, context):
        result = lib.sum(5,4)
    
        return {
            "statusCode": 200,
            "body": "hi " + result
        }
    
    

    And that's all.