How to Configure CORS Settings for Cross-Origin Requests in the FastAPI Backend
To configure CORS in the MathModelAgent FastAPI backend, set the CORS_ALLOW_ORIGINS environment variable in your .env file, and the CORSMiddleware registered in backend/app/main.py will automatically apply these settings to allow or restrict cross-origin requests.
The jihe520/mathmodelagent repository implements a centralized configuration approach for cross-origin resource sharing (CORS) that separates environment-specific settings from application logic. This architecture allows you to control which frontend origins can communicate with your backend API without modifying source code.
Understanding the CORS Architecture
The MathModelAgent backend uses FastAPI's built-in CORSMiddleware to handle cross-origin requests. The configuration flows through three distinct layers:
- Environment Layer: The
.env.dev(or production.env) file stores the rawCORS_ALLOW_ORIGINSstring - Settings Layer:
backend/app/config/setting.pyparses the environment variable into a Python list using a custom Pydantic validator - Application Layer:
backend/app/main.pyregisters the middleware with the processed settings
This separation ensures that sensitive origin URLs remain environment-specific while maintaining type safety through Pydantic validation.
Step-by-Step CORS Configuration
Configure Environment Variables
Create or edit the environment file at the repository root. For development, use .env.dev:
# backend/.env.dev
CORS_ALLOW_ORIGINS=http://localhost:5173,http://localhost:3000
The value accepts a comma-separated list of origins. To allow all origins during development (the default), use:
CORS_ALLOW_ORIGINS=*
Validate Settings Configuration
The backend/app/config/setting.py file contains the Settings class that processes the environment variable. At line 44, the CORS_ALLOW_ORIGINS field uses a custom parse_cors validator to transform the comma-separated string into a Python list:
# backend/app/config/setting.py (excerpt)
from pydantic import field_validator
from typing import List
class Settings(BaseSettings):
CORS_ALLOW_ORIGINS: List[str] = ["*"]
@field_validator("CORS_ALLOW_ORIGINS", mode="before")
@classmethod
def parse_cors(cls, value):
if isinstance(value, str):
return [origin.strip() for origin in value.split(",") if origin.strip()]
return value
This validator ensures that http://localhost:5173,http://localhost:3000 becomes ["http://localhost:5173", "http://localhost:3000"] before reaching the middleware.
Register Middleware
In backend/app/main.py, lines 38–45 instantiate the CORSMiddleware using the parsed configuration:
# backend/app/main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config.setting import settings
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ALLOW_ORIGINS, # Parsed from env variable
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
expose_headers=["*"],
)
The allow_origins parameter receives the list directly from settings.CORS_ALLOW_ORIGINS, ensuring your environment configuration controls access.
Practical Configuration Examples
Restrict to Production Domains
For a production deployment serving a specific frontend, set the environment variable to explicit domains:
CORS_ALLOW_ORIGINS=https://app.example.com,https://admin.example.com
No code changes are required; restart the FastAPI server to apply the restrictions.
Disable Credentials for Public APIs
If your MathModelAgent instance serves public data without authentication, modify the middleware parameters in backend/app/main.py:
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ALLOW_ORIGINS,
allow_credentials=False, # Disable cookie transmission
allow_methods=["GET", "OPTIONS"], # Read-only access
allow_headers=["Content-Type"],
)
Dynamic Runtime Configuration
For scenarios requiring runtime origin calculation (e.g., multi-tenant setups), modify the settings during the startup event:
@app.on_event("startup")
async def configure_cors():
# Dynamically fetch allowed origins from database or external service
tenant_origins = ["https://tenant1.com", "https://tenant2.com"]
settings.CORS_ALLOW_ORIGINS = tenant_origins
Ensure this executes before the first request arrives, as middleware configuration is baked at application startup.
Advanced CORS Customization
Beyond origin restrictions, the MathModelAgent implementation exposes standard FastAPI CORS parameters:
allow_methods: Limit HTTP verbs (e.g.,["GET", "POST"]vs["*"])allow_headers: Specify permitted headers like["Authorization", "Content-Type"]expose_headers: Make custom response headers visible to the frontendmax_age: Cache preflight responses (default varies by browser)
These parameters reside in backend/app/main.py alongside the origin configuration.
Summary
- Environment-driven: Set
CORS_ALLOW_ORIGINSin.env.devor production.envfiles to control access without code changes - Validated parsing: The
parse_corsvalidator inbackend/app/config/setting.py(line 44) converts comma-separated strings to lists - Middleware integration:
backend/app/main.py(lines 38–45) registersCORSMiddlewareusing the processed settings object - Default permissive: The repository defaults to
["*"](all origins) for development convenience - Type safety: Pydantic ensures the
CORS_ALLOW_ORIGINSfield always resolves to aList[str]
Frequently Asked Questions
How do I allow all origins during development?
Set CORS_ALLOW_ORIGINS=* in your .env.dev file. The parse_cors validator in backend/app/config/setting.py converts this to ["*"], which FastAPI interprets as allowing all origins. Remove or override this in production environments to prevent security vulnerabilities.
Where is the CORS configuration validated?
Validation occurs in backend/app/config/setting.py within the Settings class. The parse_cors method (referenced at line 44) ensures that string inputs from environment variables become properly formatted Python lists before the application initializes the middleware.
Can I restrict specific HTTP methods while keeping open origins?
Yes. While origins are controlled via the environment variable, HTTP methods are hardcoded in backend/app/main.py. Modify the allow_methods parameter in the CORSMiddleware instantiation to restrict verbs (e.g., change ["*"] to ["GET", "POST"]) while keeping allow_origins permissive.
Why are my CORS changes not taking effect?
FastAPI loads middleware configuration at application startup. After modifying .env.dev or environment variables, you must restart the Uvicorn server. Additionally, verify that your environment file is actually loaded—check that backend/app/config/setting.py points to the correct env file path in its model_config or Config class definition.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →