Spaces:
Sleeping
Sleeping
| """Proxy the generated demo app through the main Gradio Space.""" | |
| from __future__ import annotations | |
| import os | |
| import httpx | |
| from fastapi import Request, Response | |
| from starlette.responses import RedirectResponse | |
| PREVIEW_PATH = os.getenv("AI_AGENTIC_CODER_PREVIEW_PATH", "/generated-app").rstrip("/") or "/generated-app" | |
| PREVIEW_PORT = int(os.getenv("AI_AGENTIC_CODER_PREVIEW_PORT", "7861")) | |
| PREVIEW_API_PREFIXES = ( | |
| "/gradio_api", | |
| "/queue", | |
| "/call", | |
| "/reset", | |
| "/heartbeat", | |
| "/component_server", | |
| ) | |
| def _is_generated_app_request(request: Request) -> bool: | |
| referrer = request.headers.get("referer", "") | |
| return f"{PREVIEW_PATH}/" in referrer or referrer.rstrip("/").endswith(PREVIEW_PATH) | |
| def _is_generated_app_api_request(request: Request) -> bool: | |
| return request.url.path.startswith(PREVIEW_API_PREFIXES) and _is_generated_app_request(request) | |
| async def _proxy_to_preview(request: Request, target_path: str) -> Response: | |
| target_path = target_path.lstrip("/") | |
| target = f"http://127.0.0.1:{PREVIEW_PORT}/{target_path}" | |
| if request.url.query: | |
| target = f"{target}?{request.url.query}" | |
| headers = { | |
| key: value | |
| for key, value in request.headers.items() | |
| if key.lower() not in {"host", "content-length"} | |
| } | |
| try: | |
| async with httpx.AsyncClient(follow_redirects=False, timeout=300.0) as client: | |
| upstream = await client.request( | |
| request.method, | |
| target, | |
| headers=headers, | |
| content=await request.body(), | |
| ) | |
| except httpx.RequestError: | |
| return Response( | |
| "The generated preview app is not running yet, or it has expired.", | |
| status_code=503, | |
| media_type="text/plain", | |
| ) | |
| excluded_headers = { | |
| "connection", | |
| "content-encoding", | |
| "content-length", | |
| "transfer-encoding", | |
| } | |
| response_headers = { | |
| key: value | |
| for key, value in upstream.headers.items() | |
| if key.lower() not in excluded_headers | |
| } | |
| location = response_headers.get("location") | |
| if location and location.startswith(f"http://127.0.0.1:{PREVIEW_PORT}/"): | |
| response_headers["location"] = location.replace( | |
| f"http://127.0.0.1:{PREVIEW_PORT}", | |
| PREVIEW_PATH, | |
| 1, | |
| ) | |
| return Response( | |
| upstream.content, | |
| status_code=upstream.status_code, | |
| headers=response_headers, | |
| media_type=upstream.headers.get("content-type"), | |
| ) | |
| def register_preview_proxy(app) -> None: | |
| if getattr(app.state, "ai_agentic_coder_preview_proxy_registered", False): | |
| return | |
| app.state.ai_agentic_coder_preview_proxy_registered = True | |
| async def generated_app_api_proxy(request: Request, call_next): | |
| if _is_generated_app_api_request(request): | |
| return await _proxy_to_preview(request, request.url.path) | |
| return await call_next(request) | |
| async def preview_root() -> RedirectResponse: | |
| return RedirectResponse(f"{PREVIEW_PATH}/") | |
| async def proxy(request: Request, path: str = "") -> Response: | |
| return await _proxy_to_preview(request, path) | |
| methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"] | |
| app.add_api_route(PREVIEW_PATH, preview_root, methods=["GET"], include_in_schema=False) | |
| app.add_api_route(f"{PREVIEW_PATH}/{{path:path}}", proxy, methods=methods, include_in_schema=False) | |