Introduction
In this post, I will explain how to deploy FastAPI to a Lambda function, using the Typescript-based AWS CDK.
Prerequisite
This article is intended for those who have experience building Lambda functions and API Gateways with Typescript-based AWS CDK.
- Setup of AWS CDK and AWS CLI is omitted.
- Python setup is omitted.
- FastAPI description is omitted.
Development Environment
- node v18.5.0
- CDK 2.83.1
- Python 3.11.3
Install the following
pip install fastapi
pip install mangum
pip install uvicorn
Create the app
mkdir sample-ts-fastapi
cd sample-ts-fastapi
cdk init --language typescript
npm install @aws-cdk/aws-lambda-python-alpha
Reference
@aws-cdk/aws-lambda-python-alpha
Defining Lambda and API Gateway
Modify lib/sample-ts-fastapi-stack.tsas
follows.
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { PythonFunction } from "@aws-cdk/aws-lambda-python-alpha";
import { Runtime } from "aws-cdk-lib/aws-lambda";
import { LambdaRestApi } from "aws-cdk-lib/aws-apigateway";
export class SampleTsPyFastapiStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const apiName = `SampleApi`;
const lambdaName = `MyLambda`;
const lambda = new PythonFunction(this, lambdaName, {
entry: "lambda",
runtime: Runtime.PYTHON_3_10,
index: "main.py",
handler: "handler",
environment: {},
});
const api = new LambdaRestApi(this, apiName, {
handler: lambda,
});
}
}
Create Lambda Function
The directory and file structure should be as follows.
Create main.py and user.py.
lambda/
├ main.py
├ router/
└ user.py
main.py
from fastapi import FastAPI
from mangum import Mangum
from .routers import user
app = FastAPI()
@app.get("/", tags=["root"])
async def root():
return {"message": "Hello World"}
app.include_router(user.router)
handler = Mangum(app, lifespan="off")
user.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/user", tags=["user"])
async def getUser():
return {"message": "test user"}
Let’s try to run it in this state.
uvicorn lambda.main:app --reload
The API created on this page is now displayed. http://127.0.0.1:8000/docs
Deploy
- Modify
from routers import user
in main.py. (It did not pass at.routers
.) - Launch Docker in advance
cdk deploy
Adding the lambda layer
Since we are using FastAPI and Mangum, we create and add two layer.
There is also a way to include the Lambda Layer with the CDK and deploy it, but this time we did it by creating it separately.
- Create s3 bucket
- Zip the Python library
- Upload zip to s3
- Copy its Object URL
- Create layers from the lambda page (Object URL is required)
- Once the layer is created, copy its ARN
For 2 and 3, for example, create it this way.
pip install -t python/ fastapi
zip -r layer1.zip python
aws s3 cp layer1.zip s3://{backet name}/layer1.zip
Now that we have created two layers, FastAPI and Mangum, we can add them to the lambda function described earlier.
From the Lambda page of the AWS console, go to the function details page and add two layers. Enter the ARN from earlier here.
This completes the setup.
Conclusion
That’s it, I was able to get Python’s FastAPI to work with Lambda on the Typescript-based AWS CDK.
However, I could not figure out why the import path in the main.py code would not pass in Lambda unless I did it this way.
I am a beginner in Python. If there is a way to write code that can be executed without worrying about the difference between the path environment on Lambda and the local path environment, I would appreciate it if someone could tell me.
Top comments (0)