Adding CORS in Python FastAPI app deployed in Azure

Satwiki De
3 min readSep 8, 2023

--

This is a continuation from my previous article. Check it out here if you haven’t already! :)

So far, we have deployed a Python FastAPI app to Azure Web App using GitHub action and able to access the APIs through browser or Postman tool. However the ultimate goal of publishing an API service is to consume the APIs in another service, possibly a front-end app.

In case the front-end app is hosted in another server, it wouldn’t be able to access our APIs immediately due to CORS not being enabled in the backend app. We need to so some further tweaks in order to make it work end-to-end.

To figure out how CORS works for a Python FastAPI app, I have created a quick, simple React app using VS code and GitHub Copilot. Also did some modification the APIs created in previous article. Take a look at the code here.

The front-end app is running on localhost, and when I call any API from our previously published web app, I get this error in browser console —

In short, localhost:300 is not allowed to access our web app as per CORS policy.

What is CORS?

Web browsers have a strict same origin policy as part of its security restriction to not allow a webpage to call APIs in different domain. Let’s say your front-end App is running onlocalhost or domain-a.com and API service is hosted in domain-b.com then requests from localhost or domain-a.com to access domain-b.com will get restricted in browser.

CORS (Cross-Origin Resource Sharing) allows front-end apps to access resources in different domain securely.

As per MDN docs —

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.

Learn more here

Solution

#1 Update your FastAPI app

Update the code in main.py as following —

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import todolist_service

class Input(BaseModel):
text: str

# Define the app
app = FastAPI(
title="MyApp",
description="Hello API developer!",
version="0.1.0"
)

origins = [
"http://localhost",
"http://localhost:3000",
]

app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
expose_headers=["*"]
)

# APIs.... #

The code is pretty much self-explanatory — we use CORSMiddleware module from FastAPI to allow requests from selected origins. There are few things to keep in mind:

allow_origins=["*"] will allow any origin and seems like an easy, one-stop solution, however it’s important to explicitly declare the list of origins. Primary reason being security for backend app, also if we need to set allow_credentials as True then allow_origins cannot be set to ['*'] for credentials to be allowed.

Reference: https://fastapi.tiangolo.com/tutorial/cors/

#2 Enable CORS in Azure App Service

Open your Web App in Azure portal and navigate to CORS section to update the origins. This is required for all the frameworks supported by App service.

Alternatively, we can add an Az cli script in our pipeline to enable this during deployment. If we need to add other origins later in the dev cycle, this can be a better idea from IaC (Infrastructure as Code) perspective.

# Deploy step 
# Pre-requisite: azure/login@v1
- name: 'Allow basic publishing credentials access'
uses: azure/CLI@v1
with:
inlineScript: |
az webapp cors add --resource-group article --name mywebapp-sample --allowed-origins 'http://localhost:3000'

Once CORS updates are completed, and python app is deployed, then test your front-end app again, which should be able to call the APIs successfully now. :)

Hope this article helped in your Python & Azure journey. Please leave a comment if you have any feedback for me.

--

--

Satwiki De

Software Engineer | Experienced in App Dev, Cloud-native solutions, DevOps & Generative AI | Curious explorer of tech and life