Gradio registers its own "/" during launch(), so insert our index route
ahead of it in the router list — Starlette takes the first match. Gradio's
API and queue routes are untouched, so ZeroGPU allocation still works while
the root URL now serves the vanilla JS frontend.
Frontend probes both /gradio_api/call and /call so an SDK version bump
doesn't silently break the GPU call.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Use demo.launch() as entrypoint, attach custom routes after
mount_gradio_app (root or sub-path) never passed ZeroGPU's startup
scan, and HF's own docs only demonstrate .launch() for ZeroGPU. Switch
to launch(prevent_thread_lock=True) to get the officially-supported
registration path, then mount /api and /ui onto the same live app
instance it returns, and block the main thread with block_thread().
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mount Gradio at root for ZeroGPU startup detection
ZeroGPU's startup scan appears to require Gradio mounted at the app
root, not a sub-path — a working reference (GradLLM on HF) uses
path="/". Custom vanilla JS UI now lives at /ui instead, with static
files and future API routes registered before the root-level Gradio
mount so they aren't shadowed by its catch-all.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
app.py built the FastAPI+Gradio app but never served it, so the
container ran to completion and exited 0 with nothing listening on
7860.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Gradio is mounted at /gradio purely as the ZeroGPU harness. Custom
routes live on /api/*, and the vanilla JS UI is served at / via
StaticFiles. Previous crash was StaticFiles raising on a missing
frontend/ directory that hadn't actually been pushed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Strip down to bare demo.launch() to verify @spaces.GPU allocation
works before layering FastAPI + static frontend back on top.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>