from flask import Flask, request, Response import requests from flask_cors import CORS app = Flask(__name__) # Enable CORS for all routes and all origins CORS(app, resources={r"/*": {"origins": "*"}}, supports_credentials=True) ANTHROPIC_API_BASE = "https://api.anthropic.com" @app.route( "/v1/", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"] ) def proxy(subpath): # For preflight OPTIONS requests, return immediately with appropriate CORS headers if request.method == "OPTIONS": response = Response() response.headers.add("Access-Control-Allow-Origin", "*") response.headers.add("Access-Control-Allow-Headers", "*") response.headers.add( "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS" ) response.headers.add("Access-Control-Allow-Credentials", "true") response.headers.add("Access-Control-Max-Age", "3600") return response # Construct the target URL target_url = f"{ANTHROPIC_API_BASE}/v1/{subpath}" # Get the request headers headers = { key: value for key, value in request.headers if key.lower() not in ("host", "origin", "referer", "accept-encoding") } # Explicitly set Accept-Encoding to identity to avoid gzip compression headers["Accept-Encoding"] = "identity" # Convert Authorization: Bearer to x-api-key auth_header = headers.get("Authorization") if auth_header and auth_header.startswith("Bearer "): token = auth_header.replace("Bearer ", "") headers["x-api-key"] = token # Remove the original Authorization header if "Authorization" in headers: del headers["Authorization"] # Get the request data/params data = request.get_data() params = request.args # Add Anthropic-specific headers headers["Anthropic-Version"] = "2023-06-01" # Forward the request to Anthropic API resp = requests.request( method=request.method, url=target_url, headers=headers, data=data, params=params, stream=True, # Always use stream=True to handle both streaming and non-streaming responses ) # Create a Flask response object def generate(): for chunk in resp.iter_content(chunk_size=1024): yield chunk response = Response( generate(), status=resp.status_code, content_type=resp.headers.get("Content-Type"), ) # Copy only required headers from the Anthropic response to our response excluded_headers = ( "transfer-encoding", "content-length", "connection", "content-encoding", "vary", "accept-ranges", ) for key, value in resp.headers.items(): if key.lower() not in excluded_headers: response.headers[key] = value # Add CORS headers to the response response.headers.add("Access-Control-Allow-Origin", "*") response.headers.add("Access-Control-Allow-Credentials", "true") return response if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)