from fastapi import FastAPI, Request, Response, HTTPException from fastapi.middleware.cors import CORSMiddleware import httpx import uvicorn from typing import Dict, Any, Optional import os app = FastAPI(title="LLM7.io API Proxy") # Configure CORS for all origins app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Target API URL TARGET_API_URL = "https://api.llm7.io" @app.get("/") async def root(): return { "status": "online", "message": "LLM7.io API Proxy is running. Send requests to /v1/... endpoints.", "usage": "This proxy forwards requests to api.llm7.io. No API key is required." } @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"]) async def proxy(path: str, request: Request): """ Proxy all requests to the LLM7.io API. This handles any path and HTTP method, forwarding the request to the target API. """ # Construct target URL target_url = f"{TARGET_API_URL}/{path}" # Get request body if present body = None if request.method in ["POST", "PUT", "PATCH"]: try: body = await request.json() except Exception: try: body = await request.body() except Exception: body = None # Get request headers, excluding host headers = dict(request.headers) headers.pop("host", None) # Create httpx client with timeout async with httpx.AsyncClient(timeout=120.0) as client: try: # Forward the request to the target API response = await client.request( method=request.method, url=target_url, headers=headers, json=body if isinstance(body, dict) else None, content=body if not isinstance(body, dict) and body is not None else None, params=request.query_params, follow_redirects=True ) # Create response with same status code and content, but filter headers # Remove problematic headers that could cause Content-Length issues response_headers = dict(response.headers) # Remove content-length header to let FastAPI calculate it correctly response_headers.pop("content-length", None) # Also remove transfer-encoding as it can conflict with content-length response_headers.pop("transfer-encoding", None) return Response( content=response.content, status_code=response.status_code, headers=response_headers, ) except httpx.RequestError as exc: raise HTTPException(status_code=503, detail=f"Error forwarding request: {str(exc)}") if __name__ == "__main__": # Get port from environment variable or use default port = int(os.environ.get("PORT", 7860)) # Run the server uvicorn.run(app, host="0.0.0.0", port=port)