The Ultimate Guide to Deploying FastAPI on AWS Lambda and API Gateway using AWS SAM

fastapi lambda

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,

  1. 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 a main.py file.
  2. 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.

  1. 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.
  2. 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

  1. Install the AWS SAM CLI as per the steps mentioned in the AWS article.
  2. 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.

  1. In the AWS SAM template.yaml, the codeuri is configured as root folder and the handler method is provided as lambda_handler available in the main.py file.
  2. 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.
  3. The /items GET and POST api endpoints are defined with the event names ItemGet and ItemPost
  4. To test this FastAPI application as AWS Lambda locally using the AWS SAM, first build the application with command sam build
  5. 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, sam local start api

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.