voice-notes / space_app.py
osina's picture
Fix Gradio startup probe
b1fd1ba verified
Raw History Blame Contribute Delete
1.63 kB
from __future__ import annotations
import logging
import os
import threading
import spaces
from gradio import Server
from app.config import get_settings
from app.factory import create_app
logger = logging.getLogger(__name__)
GRADIO_DOC_ROUTES = {"/docs", "/openapi.json", "/redoc", "/docs/oauth2-redirect"}
@spaces.GPU(duration=1)
def _zero_gpu_probe() -> str:
"""Satisfy the ZeroGPU runtime requirement; the demo itself runs on CPU."""
return "ok"
def _warm_whisper(transcriber) -> None:
try:
transcriber.warm_up()
logger.info("Whisper model is loaded and ready")
except Exception:
logger.exception("Whisper warm-up failed; the first request will retry")
settings = get_settings()
api = create_app(settings)
# Gradio's Server owns the outer FastAPI instance. Mount the real application at
# the root so the dashboard, API, WebSocket, and docs are served unchanged.
demo = Server(title=settings.app_name)
@demo.get("/gradio_api/startup-events")
def _gradio_startup_events() -> dict[str, str]:
# Gradio's launch() probes this path. The root mount below would otherwise
# shadow Gradio's own handler, and the probe would fail with a 404.
return {"status": "ok"}
demo.mount("/", api)
demo.routes[:] = [
route for route in demo.routes if getattr(route, "path", None) not in GRADIO_DOC_ROUTES
]
if os.environ.get("SPACE_WARMUP", "1") == "1":
threading.Thread(
target=_warm_whisper,
args=(api.state.transcriber,),
name="whisper-warmup",
daemon=True,
).start()
if __name__ == "__main__":
demo.launch(ssr_mode=False)