How to configure CORS in Python Flask

Enable Cross-Origin Resource Sharing (CORS) in a Python Flask application using the flask-cors package or manual response headers.

Configure Cross-Origin Resource Sharing (CORS) in a Python Flask application using the flask-cors package to allow cross-origin requests from specific or all origins.

Prerequisites

  • Python 3.8 or later installed.
  • A Flask application.
  • pip for package management.

Step-by-Step: Enable CORS in Python Flask

  1. Install the flask-cors package. This package provides Flask extensions that add Cross-Origin Resource Sharing (CORS) response headers:

    pip install flask-cors
  2. Import CORS from flask_cors and apply it to the Flask application.

    Option A: Allow all origins-- Wrap the Flask app with CORS(app) to permit requests from any origin:

    from flask import Flask
    from flask_cors import CORS
    
    app = Flask(__name__)
    CORS(app)
    
    @app.route('/api/data')
    def get_data():
        return {'message': 'CORS enabled for all origins'}

    Option B: Allow a specific origin-- Pass the origins parameter to restrict CORS access:

    from flask import Flask
    from flask_cors import CORS
    
    app = Flask(__name__)
    CORS(app, origins=['https://app.example.com'], supports_credentials=True)
    
    @app.route('/api/data')
    def get_data():
        return {'message': 'CORS enabled for app.example.com'}

    Option C: Apply CORS to specific routes-- Use the @cross_origin() decorator to enable CORS on individual endpoints instead of the entire application:

    from flask import Flask
    from flask_cors import cross_origin
    
    app = Flask(__name__)
    
    @app.route('/api/public')
    @cross_origin()
    def public_endpoint():
        return {'message': 'This endpoint allows all origins'}
    
    @app.route('/api/private')
    @cross_origin(origins='https://app.example.com', supports_credentials=True)
    def private_endpoint():
        return {'message': 'This endpoint allows only app.example.com'}

    Option D: Set CORS headers manually-- Use Flask's after_request hook to set Cross-Origin Resource Sharing headers without the flask-cors package:

    from flask import Flask, request
    
    app = Flask(__name__)
    
    @app.after_request
    def add_cors_headers(response):
        response.headers['Access-Control-Allow-Origin'] = 'https://app.example.com'
        response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
        response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
        response.headers['Access-Control-Allow-Credentials'] = 'true'
        return response

How to Verify CORS Is Working in Flask

Start the Flask development server and send a test request with curl to confirm Cross-Origin Resource Sharing (CORS) headers appear in the response:

curl -I -H "Origin: https://app.example.com" http://localhost:5000/api/data

The response should include:

Access-Control-Allow-Origin: https://app.example.com

Common Issues When Configuring CORS in Flask

  • CORS(app) called after route registration.Flask-CORS must wrap the app before routes are defined if applied globally. Call CORS(app) immediately after creating the Flask instance.
  • Credentials rejected with wildcard.Flask-CORS defaults to Access-Control-Allow-Origin: *. Set the origins parameter to a specific domain when supports_credentials=True.
  • Duplicate CORS headers from reverse proxy.Nginx or Apache sets CORS headers that conflict with Flask's headers. Configure CORS in one layer only.

For a detailed explanation of the CORS mechanism, see CORS tutorial: How Cross-Origin Resource Sharing works.