Python relative imports in AWS Lambda fail with attempted relative import with no known parent package
In AWS Lambda if I attempt an explicit relative import like this
.
├── lambda_file.py
└── example.py
# lambda_file.py
from .example import lambda_handler
# example.py
def lambda_handler(event, context):
return True
And I configure AWS Lambda's handler to lambda_file.lambda_handler
I get the following errors
- Python 2.7 :
Attempted relative import in non-package
- Python 3.7 :
attempted relative import with no known parent package
PEP008 says :
Implicit relative imports should never be used and have been removed in Python 3.
If I change lambda_file.py
to contain the following, it works, but no longer uses explicit relative imports
# lambda_file.py
from example import lambda_handler
The solution is to ensure that the "Handler" value that you configure in AWS Lambda contain at least 2 .
periods. To achieve this you need to put your code within a directory in your AWS Lambda code zip file and make that directory a module by adding an empty __init__.py
file. The resulting structure looks like this
.
├── app
│ ├── __init__.py
│ ├── lambda_file.py
│ └── example.py
And you now change the "Handler" value from lambda_file.lambda_handler
to app.lambda_file.lambda_handler
- AWS Lambda loads your handler as a module import not as a top-level script
- This solution came after reading this explanation of explicit relative imports by Brendan Barnwell
Deploying with container images
If you are Deploying container images, you may also need to make these modifications.
This is before breaking into multiple files.
After with the lambda_handler in the
__init__.py
You will also need to rework the Dockerfile COPY commands from
to
Via this method, you can keep the CMD command the same
CMD ["app.lambda_handler"]
This is what I had to do to get it to work for me.