Spaces:
Running
Running
fix: keep Gradio native launch; monkey-patch /video onto its own FastAPI (fixes /_app/immutable 404)
Browse files
app.py
CHANGED
|
@@ -504,19 +504,19 @@ if __name__ == "__main__":
|
|
| 504 |
# <video> sources (hf.space iframe → xet CDN). We dodge this by streaming
|
| 505 |
# the mp4 through this Space's own FastAPI app so the browser sees the
|
| 506 |
# video on the same origin as the page.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 507 |
import httpx
|
| 508 |
-
import
|
| 509 |
-
from fastapi import FastAPI, HTTPException, Request
|
| 510 |
from fastapi.responses import StreamingResponse
|
|
|
|
| 511 |
|
| 512 |
-
fastapi_app = FastAPI()
|
| 513 |
_video_client = httpx.AsyncClient(timeout=30.0, follow_redirects=True)
|
| 514 |
|
| 515 |
-
@fastapi_app.api_route(
|
| 516 |
-
"/video/{model}/{task_id}.mp4",
|
| 517 |
-
methods=["GET", "HEAD"],
|
| 518 |
-
include_in_schema=False,
|
| 519 |
-
)
|
| 520 |
async def _proxy_video(model: str, task_id: str, request: Request):
|
| 521 |
if model not in MODELS or task_id not in TASK_BY_ID:
|
| 522 |
raise HTTPException(404, "unknown (model, task_id)")
|
|
@@ -552,8 +552,23 @@ if __name__ == "__main__":
|
|
| 552 |
headers=passthrough_headers,
|
| 553 |
)
|
| 554 |
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 559 |
|
|
|
|
| 504 |
# <video> sources (hf.space iframe → xet CDN). We dodge this by streaming
|
| 505 |
# the mp4 through this Space's own FastAPI app so the browser sees the
|
| 506 |
# video on the same origin as the page.
|
| 507 |
+
#
|
| 508 |
+
# IMPORTANT: we attach to Gradio's *own* FastAPI app (populated lazily
|
| 509 |
+
# during `.launch()`). Using gr.mount_gradio_app + a hand-built FastAPI
|
| 510 |
+
# was a mistake — it drops Gradio's `/_app/immutable/*` static-asset
|
| 511 |
+
# routes, causing the UI to render as a bare HTML skeleton on
|
| 512 |
+
# browsers that haven't cached the old bundle.
|
| 513 |
import httpx
|
| 514 |
+
from fastapi import HTTPException, Request
|
|
|
|
| 515 |
from fastapi.responses import StreamingResponse
|
| 516 |
+
from gradio.routes import App as _GradioApp
|
| 517 |
|
|
|
|
| 518 |
_video_client = httpx.AsyncClient(timeout=30.0, follow_redirects=True)
|
| 519 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 520 |
async def _proxy_video(model: str, task_id: str, request: Request):
|
| 521 |
if model not in MODELS or task_id not in TASK_BY_ID:
|
| 522 |
raise HTTPException(404, "unknown (model, task_id)")
|
|
|
|
| 552 |
headers=passthrough_headers,
|
| 553 |
)
|
| 554 |
|
| 555 |
+
# Monkey-patch Gradio's App.create_app so that right after Gradio builds
|
| 556 |
+
# its own FastAPI app (with all the /_app/immutable/* routes, /gradio_api
|
| 557 |
+
# endpoints, etc.) we register the video proxy on the same instance.
|
| 558 |
+
_orig_create_app = _GradioApp.create_app
|
| 559 |
+
|
| 560 |
+
def _patched_create_app(*args, **kwargs):
|
| 561 |
+
app = _orig_create_app(*args, **kwargs)
|
| 562 |
+
app.add_api_route(
|
| 563 |
+
"/video/{model}/{task_id}.mp4",
|
| 564 |
+
_proxy_video,
|
| 565 |
+
methods=["GET", "HEAD"],
|
| 566 |
+
include_in_schema=False,
|
| 567 |
+
)
|
| 568 |
+
print("[mbench-ann] /video proxy route registered on Gradio's own app")
|
| 569 |
+
return app
|
| 570 |
+
|
| 571 |
+
_GradioApp.create_app = staticmethod(_patched_create_app)
|
| 572 |
+
|
| 573 |
+
demo.queue(default_concurrency_limit=16).launch()
|
| 574 |
|