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")