The Ultimate Guide to Deploying FastAPI on AWS Lambda and API Gateway using AWS SAM
Learn how to deploy Serverless FastAPI Application on AWS Lambda and API Gateway using AWS SAM.
FastAPI, is a modern, fast (high-performance), web framework enabling REST API creation.
The main features of the FastAPI includes:
Swift: Exceptionally high performance, equivalent to NodeJS and Go (owing to Starlette and Pydantic). Among the swiftest Python frameworks accessible. Efficient in development: Accelerate feature development by approximately 200% to 300%. * Reduced errors: Mitigate around 40% of human (developer) induced mistakes. * Intuitive: Exceptional editor support. Auto-completion throughout. Less time spent on debugging. User-friendly: Tailored for ease of utilization and learning. Less time required for manual perusal of documentation. Concise: Minimize redundancy in code. Multiple functionalities from each parameter declaration. Fewer errors. Sturdy: Attain production-ready code with automatic interactive documentation. Compliant with standards: Rooted in (and fully interoperable with) the established standards for APIs: OpenAPI (formerly known as Swagger) and JSON Schema.
In this blog, we shall delve into the intricacies of developing a FastAPI AWS Lambda, local invocation and testing through AWS SAM, and deployment as an AWS Lambda coupled with API Gateway leveraging the prowess of AWS SAM.
Developing the AWS Lambda FastAPI Application
The blog is written based on the following versions,
- Python: 3.10.13
- FastAPI: 4.2.2
- AWS SAM: 1.97.0
FastAPI isn't initially tailored for seamless integration with serverless architectures. To bridge this gap, we necessitate the employment of an adapter specifically tailored for executing ASGI (Asynchronous Server Gateway Interface) applications like FastAPI within AWS Lambda, thereby proficiently managing the intricacies of API Gateway events. These adapters play a pivotal role in translating Lambda events into a format comprehensible to the FastAPI APIrouter, ensuring its seamless operation as an ASGI application.
In this context, we leverage the Python package, Mangum
, to accomplish this integration. Mangum serves as a vital adapter, specifically designed for orchestrating ASGI applications within AWS Lambda, effectively managing various event sources like Function URLs, API Gateway, Application Load Balancer (ALB), and Lambda@Edge events.
Lets create a new aws lambda fastapi project for this blog following the below steps,
- Structure a new folder layout for this project and include a subfolder
src
. Within this subdirectory, generate an empty__init__.py
Python file, and additionally, produce amain.py
file. - Within the
main.py
file, insert the provided code snippet.
import os
from fastapi import FastAPI
from mangum import Mangum
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "FastAPI running on AWS Lambda and is executed in region " + os.env["AWS_REGION"] + ", using runtime environment " + os.env["AWS_EXECUTION_ENV"]}
@app.get("/items")
def read_item():
return {"item_id": 1}
@app.post("/items")
async def create_item(item: Item):
return item
lambda_handler = Mangum(app, lifespan="off")
In this file, we commence by importing vital dependencies, namely FastAPI
and Mangum
. Subsequently, we proceed to define our API routes, employing the FastAPI APIRouter methodology, intricately aligning them with their respective underlying methods. Finally, the ultimate line of code encapsulates the FastAPI object app
within Mangum
, a pivotal maneuver facilitating the harmonization of AWS Lambda API Gateway events with FastAPI's intricate routing mechanisms.
- There are three api end points defined using FastAPI APIrouter. Two Get api methods - one being the base root
/
path and the other/items
. Third api route is a POST method for the end point/items.
- Create a new
requirements.txt
file and add the following packages to it,
fastapi==0.103.1
uvicorn==0.23.2
mangum==0.17.0
AWS SAM Setup for local testing the lambda FastAPI application
- Install the AWS SAM CLI as per the steps mentioned in the AWS article.
- Creata new AWS SAM
template.yaml
by copying the below content,
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Sample SAM Template for fast-api
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 15
MemorySize: 128
Resources:
ItemFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: .
Handler: src/main.lambda_handler
Runtime: python3.10
Architectures:
- x86_64
Events:
ItemBase:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /
Method: get
Swagger:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /docs
Method: get
Openapi:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /openapi.json
Method: get
ItemGet:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /items
Method: get
ItemPost:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /items
Method: post
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
APIGatewayHost:
Description: "API Gateway endpoint HOST for Prod stage for Item function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
ItemFunction:
Description: "Item Lambda Function ARN"
Value: !GetAtt ItemFunction.Arn
The AWS SAM template.yaml
is configured with a resource type of AWS::Serverless::Function
and is attached with multiple events as the trigger.
- In the AWS SAM template.yaml, the codeuri is configured as root folder and the handler method is provided as
lambda_handler
available in themain.py
file. - All the api routes defined in this FastAPI application is defined in this template.yaml under Events along with additional routes
(/docs,/openapi.json)
to expose the FastAPI automatic swagger docs. This is optional event and can be removed if not required. - The
/items
GET and POST api endpoints are defined with the event namesItemGet
andItemPost
- To test this FastAPI application as AWS Lambda locally using the AWS SAM, first build the application with command
sam build
- Lets invoke the application with command
sam local start-api
and it should initialize the lambda functions containers and expose the api end points through localhost as shown below,
Deploy FastAPI AWS Lambda Serverless Application using AWS SAM
Once the local testing is completed, the next step is to deploy lambda fastapi using the AWS SAM. We will use sam deploy --guided --profile profile-name
to deploy the changes to AWS Account. SAM will take care of automatically packaging the AWS FastAPI lambdas and deploy it to the AWS account depending on the profile name passed in the command.
Once the deployment is completed, deployment command should return the fastapi lambda aws api gateway end point which we can use it test and integrate with other application.
Sample Repo for FastAPI AWS Lambda Repo
The entire code base for this FastAPI aws lambda app is available in the Github.