CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-flask-cors

A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

cross-origin-decorator.mddocs/

Cross-Origin Decorator

The cross_origin decorator provides route-specific Cross-Origin Resource Sharing configuration for individual Flask routes. It offers fine-grained control over CORS settings on a per-route basis with automatic OPTIONS request handling.

Capabilities

Cross-Origin Decorator Function

Decorator function that wraps Flask route handlers to enable CORS with configurable parameters. Applied directly to route functions for granular CORS control.

def cross_origin(
    origins="*",
    methods=None,
    expose_headers=None,
    allow_headers="*",
    supports_credentials=False,
    max_age=None,
    send_wildcard=False,
    vary_header=True,
    automatic_options=True,
    allow_private_network=False,
    always_send=True,
    **kwargs
):
    """
    Decorator to enable CORS for specific Flask routes.

    Parameters:
    - origins: Allowed origins (string, list, or regex patterns)
    - methods: Allowed HTTP methods (list or string)
    - expose_headers: Headers safe to expose to CORS API (list or string)
    - allow_headers: Headers allowed in requests (list, string, or regex)
    - supports_credentials: Allow authenticated requests (bool)
    - max_age: Cache time for preflight requests (timedelta, int, or string)
    - send_wildcard: Send '*' instead of specific origin (bool)
    - vary_header: Include Vary: Origin header (bool)
    - automatic_options: Handle OPTIONS requests automatically (bool)
    - allow_private_network: Allow private network access (bool, default: False)
    - always_send: Send CORS headers even without Origin header (bool)
    - **kwargs: Additional configuration options

    Returns:
    Decorated function with CORS headers applied
    """

Usage Examples

Basic Route Decoration

from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/data")
@cross_origin()  # Allow all origins with default settings
def get_data():
    return {"message": "CORS-enabled data"}

@app.route("/api/public")
@cross_origin(origins="*")  # Explicit wildcard
def public_endpoint():
    return {"data": "public information"}

Specific Origins

from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/secure")
@cross_origin(origins=["https://trusted-site.com", "https://app.example.com"])
def secure_endpoint():
    return {"data": "restricted data"}

@app.route("/api/development")
@cross_origin(origins=["http://localhost:3000", "http://localhost:8080"])
def development_endpoint():
    return {"data": "development data"}

Regex Origins

import re
from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/subdomains")
@cross_origin(origins=r"https://.*\.example\.com")
def subdomain_endpoint():
    return {"data": "subdomain accessible"}

@app.route("/api/pattern")
@cross_origin(origins=[
    re.compile(r"https://app\d+\.example\.com"),
    "https://main.example.com"
])  
def pattern_endpoint():
    return {"data": "pattern matched"}

Method-Specific CORS

from flask import Flask, request
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/users", methods=["GET", "POST"])
@cross_origin(
    origins=["https://frontend.example.com"],
    methods=["GET", "POST"],
    allow_headers=["Content-Type", "X-Requested-With"]
)
def users_endpoint():
    if request.method == "GET":
        return {"users": []}
    elif request.method == "POST":
        return {"created": True}

Credentials Support

from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/auth/profile")
@cross_origin(
    origins=["https://app.example.com"],
    supports_credentials=True,
    allow_headers=["Content-Type", "Authorization"]
)
def user_profile():
    # This route accepts cookies and credentials
    return {"profile": "user data"}

@app.route("/api/auth/login", methods=["POST"])
@cross_origin(
    origins=["https://app.example.com"],
    supports_credentials=True,
    methods=["POST"]
)
def login():
    return {"token": "auth-token"}

Custom Headers Configuration

from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/upload", methods=["POST"])
@cross_origin(
    origins=["https://uploader.example.com"],
    allow_headers=["Content-Type", "X-File-Name", "X-Upload-Key"],
    expose_headers=["X-Upload-ID", "X-Processing-Status"],
    methods=["POST", "OPTIONS"]
)
def file_upload():
    return {"upload_id": "12345", "status": "processing"}

Preflight Caching

from datetime import timedelta
from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/heavy-operation", methods=["POST"])
@cross_origin(
    origins=["https://client.example.com"],
    max_age=timedelta(hours=1),  # Cache preflight for 1 hour
    methods=["POST"]
)
def heavy_operation():
    # Expensive operation that benefits from preflight caching
    return {"result": "computed"}

@app.route("/api/frequent-calls")
@cross_origin(
    origins=["https://dashboard.example.com"],
    max_age=3600,  # Cache for 1 hour (seconds)
    allow_headers=["Content-Type", "Authorization"]
)
def frequent_endpoint():
    return {"data": "frequently accessed"}

OPTIONS Handling Control

from flask import Flask, jsonify
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/custom-options", methods=["GET", "POST", "OPTIONS"])
@cross_origin(
    origins=["https://custom.example.com"],
    automatic_options=False  # Handle OPTIONS manually
)
def custom_options_endpoint():
    if request.method == "OPTIONS":
        # Custom preflight response
        return jsonify({"preflight": "custom response"})
    elif request.method == "GET":
        return {"data": "get response"}
    elif request.method == "POST":
        return {"data": "post response"}

Mixed Configuration

from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/complex")
@cross_origin(
    origins=[
        "https://prod.example.com",       # Production
        "https://staging.example.com",    # Staging
        r"https://.*\.dev\.example\.com", # Development subdomains
        "http://localhost:3000"           # Local development
    ],
    methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=[
        "Content-Type",
        "Authorization", 
        "X-API-Key",
        r"X-Custom-.*"  # Regex pattern for custom headers
    ],
    expose_headers=["X-Total-Count", "X-Rate-Limit-Remaining"],
    supports_credentials=True,
    max_age=1800,  # 30 minutes
    vary_header=True
)
def complex_endpoint():
    return {"data": "complex CORS configuration"}

Integration with Flask Extensions

The cross_origin decorator works seamlessly with other Flask extensions:

Flask-Login Integration

from flask import Flask
from flask_login import login_required
from flask_cors import cross_origin

app = Flask(__name__)

@app.route("/api/protected")
@cross_origin(
    origins=["https://app.example.com"],
    supports_credentials=True
)
@login_required
def protected_endpoint():
    return {"data": "protected resource"}

Flask-RESTful Integration

from flask import Flask
from flask_restful import Api, Resource
from flask_cors import cross_origin

app = Flask(__name__)
api = Api(app)

class UserResource(Resource):
    @cross_origin(origins=["https://api-client.example.com"])
    def get(self, user_id):
        return {"user_id": user_id}
    
    @cross_origin(
        origins=["https://admin.example.com"],
        methods=["POST"],
        supports_credentials=True
    )
    def post(self):
        return {"created": True}

api.add_resource(UserResource, "/api/users/<int:user_id>")

Error Handling

The decorator provides automatic error handling for common CORS scenarios:

  • Origin Rejection: Non-matching origins receive responses without CORS headers
  • Method Validation: Unsupported methods in preflight requests are rejected
  • Header Validation: Invalid headers in preflight requests are filtered
  • Credential Conflicts: Automatic validation prevents wildcard origins with credentials

Performance Considerations

  • Decorator Overhead: Minimal performance impact per request
  • Options Caching: Use max_age for frequently preflight-checked endpoints
  • Header Processing: Only specified headers are processed and validated
  • Origin Matching: Regex patterns are compiled once at decoration time

Install with Tessl CLI

npx tessl i tessl/pypi-flask-cors

docs

cors-extension.md

cross-origin-decorator.md

index.md

tile.json