from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse, Response import httpx import os import logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger("studio-proxy") app = FastAPI(title="Studio AI Command Center") API_BASE = "https://api.musicapi.ai" _client = httpx.AsyncClient(timeout=60.0) @app.on_event("shutdown") async def shutdown(): await _client.aclose() @app.get("/") async def root(): if not os.path.exists("index.html"): return HTMLResponse("

index.html not found

", status_code=500) with open("index.html", "r", encoding="utf-8") as f: return HTMLResponse(f.read()) @app.get("/api/test-key") async def test_key(request: Request): key = request.query_params.get("key", "") if not key: return {"error": "no key provided"} try: resp = await _client.get( f"{API_BASE}/api/v1/get-credits", headers={"Authorization": f"Bearer {key}"}, ) return {"status": resp.status_code, "body": resp.text[:500]} except Exception as e: return {"error": str(e)} @app.get("/api/debug-health") async def debug_health(): results = {} try: resp = await _client.get(f"{API_BASE}/api/v1/get-credits", timeout=10.0) results["direct_status"] = resp.status_code results["direct_body"] = resp.text[:200] except Exception as e: results["direct_error"] = str(e) try: resp2 = await _client.get(f"{API_BASE}/api/v1/get-credits", headers={"Authorization": "Bearer sk-test"}) results["auth_status"] = resp2.status_code results["auth_body"] = resp2.text[:200] except Exception as e: results["auth_error"] = str(e) return results @app.api_route("/api/v1/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"]) async def proxy(path: str, request: Request): url = f"{API_BASE}/api/v1/{path}" # Only forward Authorization header auth = request.headers.get("authorization", "") headers = {} if auth: headers["Authorization"] = auth body = await request.body() try: resp = await _client.request( method=request.method, url=url, headers=headers, content=body or None, ) return Response(content=resp.content, status_code=resp.status_code, headers={"Content-Type": resp.headers.get("content-type", "application/json")}) except httpx.TimeoutException: return Response(content='{"error": "proxy timeout"}', status_code=504, media_type="application/json") except Exception as e: return Response(content=f'{{"error": "proxy error: {str(e)}"}}', status_code=502, media_type="application/json")