'AWS SAM-lambda: Cannot import from parent directory containing a fastapi app
I'm trying to deploy a fastapi application to AWS lambda using the SAM client. The issue is that I cannot get Lambda to recognize the parent folder.
I have a fastapi app structure that is based on this, straight from the fastapi docs. With this app structure, I set up a SAM lambda dockerfile like so:
FROM public.ecr.aws/lambda/python:3.8
RUN yum -y install file-devel
COPY requirements.txt .
RUN pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}" && rm requirements.txt
COPY ./app ${LAMBDA_TASK_ROOT}
CMD ["app.main.handler"]
Then within the template file I've set
Handler: app.main.handler
among the other settings.
I run the SAM build, then sam local start-api
, and hit the /docs
endpoint. But SAM complains:
> sam local start-api
Mounting at http://127.0.0.1:3000/{proxy+} [DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2022-04-28 12:07:53 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Invoking Container created from myapp:sam-lambda
Image was not found.
Removing rapid images for repo myapp
Building image.................
Skip pulling image and use local one: myapp:rapid-1.43.0-x86_64.
START RequestId: 793d031e-ad4a-431d-a9a7-7dd5744f2bef Version: $LATEST
Traceback (most recent call last): Unable to import module 'app.main': No module named 'app'
END RequestId: 793d031e-ad4a-431d-a9a7-7dd5744f2bef
REPORT RequestId: 793d031e-ad4a-431d-a9a7-7dd5744f2bef Init Duration: 0.20 ms Duration: 120.60 ms Billed Duration: 121 ms Memory Size: 10000 MB Max Memory Used: 10000 MB
Lambda returned empty body!
Invalid lambda response received: Invalid API Gateway Response Keys: {'errorMessage', 'stackTrace', 'errorType'} in {'errorMessage': "Unable to import module 'app.main': No module named 'app'", 'errorType': 'Runtime.ImportModuleError', 'stackTrace': []}
2022-04-28 12:08:03 127.0.0.1 - - [28/Apr/2022 12:08:03] "GET /docs HTTP/1.1" 502 -
I suspect I need to set the proper path somewhere, or the PYTHONPATH
, but I've tried a million combinations. It seems like the app directory itself is not recognized by python within the container, maybe because it is a level above what the docker container can see? All my routes throughout the fastapi app are pegged to the parent app/
folder, e.g.
from app.main import handler
etc...
Any help is appreciated.
Solution 1:[1]
Answering my own question for anybody that stumbles upon this:
The original problem was caused by another directory in the application that was not added.
Changing the Dockerfile to this:
FROM public.ecr.aws/lambda/python:3.8
RUN yum -y install file-devel
COPY requirements.txt .
RUN pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}" && rm requirements.txt
COPY . ${LAMBDA_TASK_ROOT}
CMD ["app.main.handler"]
was one way to solve it.
However, the truly brutal part about this was that SAM lambda has a quirk when using Docker custom container. If you run
sam build --use-container
sam local start-api
your changes won't be reflected! What you need is this flag:
sam build --use-container
sam local start-api --force-image-build
This was what burned most of my time. Always use the --force-image-build
flag when using your own Dockerfile with SAM.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | John Kealy |