AWS Lambda + FastAPI + Mangum – Migrating APIs to FastAPI

  amazon-web-services, fastapi, lambda, python

I have a Lambda function handler which takes in a request, and classify into REST or HTTP based on the call and preprocess it inpreprocess_and_call to go through validation of the call, and finally makes a call to the backend API endpoints, gets and return the response.

My current Lambda function (main.py) is set up like this:

# Lambda handler
def handler(event, context):
    # if REST call
    if event.get('routeKey', None) == "$default" and 'rawPath' in event: 
        path = event.get('path', None)
        # ... parse other parameters such as method, headers, etc ...
    # else if HTTP call
    elif event.get('path', None):
        path = event.get('rawPath', None)
        # ... parse other parameters such as method, headers, etc ...

    return preprocess_and_call(path, method, headers, query_params, body)

# calls the endpoints after validation, authrization, etc
def preprocess_and_call(path, method, headers, query_params, body):
     try:
         if path in endpoints_list:
            endpoint_to_call = endpoints_list[path]
            # ... validation logics here ...
            response = endpoint_to_call(path, method, headers, query_params, body)
            return response
     except Exception as ex:
            ... return error ...

This is one of the sample endpoints:

def sample_endpoint(path, method, headers, query_params, body):
   try:
       id = query_paraams.get('id', None)
       model = SampleModel()
       model.process()
       response_body = model.json()
       return {
          'status_code': 200,
          'body': response_body
       }
       
   except Exception as ex:
        # ... process exception ... 

I am trying to move my lambda function + APIs to make use of FastAPI + Mangum and this is what I have so far:

Currently, my lambda handler is set up using FastAPI middleware decorator and Mangum like the following (Mangum works as an adapter for ASGI applications like the ones you can create with fastAPI so that they can send and receive information from API Gateway to Lambda and vice versa. I removed handler because Mangum provides HTTP and REST support, which should probably be undone):

from routers import router

app = FastAPI()

app.include_router(router)

# Handler for api calls
@app.middleware("http")
async def preprocess_and_call(request: Request, call_next):
    try:
        if path in endpoints_list:
            # ... validation logics here ...

            response = await call_next(request) # calls the endpoints with corresponding path

            # ... process the response ...
  
   except Exception as ex:
        # ... process exception ...


handler = Mangum(app)

And I have several endpoints which gets called from the above lambda function, do their job and return the response accordingly like this:

@router.get("/index")
def sample_endpoint(request: Request):
   try:
       query_params= request.query_params
       # ....
       return Response(
           status_code = 200,
           content=json.dumps(response_body)
       )
   except Exception as ex:
        # ... process exception ...

However, I believe this is not the 100% correct way of doing it. For example, Im not sure if using middleware in this case is the right way or not. Any suggestions would be greatly appreciated!

Source: Python Questions

LEAVE A COMMENT