cazyundee commited on
Commit
62b3862
·
verified ·
1 Parent(s): 317bb04

Use /respite/ prefix to avoid Gradio proxy conflict

Browse files
Files changed (1) hide show
  1. app.py +33 -30
app.py CHANGED
@@ -7,7 +7,6 @@ import torch
7
  import torchaudio
8
  import gradio as gr
9
  import spaces
10
- from fastapi import FastAPI
11
  from fastapi.responses import JSONResponse
12
  from einops import rearrange
13
  from huggingface_hub import login
@@ -79,11 +78,11 @@ API_SPECS = {
79
  "name": "Respite API",
80
  "version": "1.0.0",
81
  "description": "General-purpose AI API server with audio generation capabilities.",
82
- "base_path": "/api",
83
  "authentication": "none",
84
  "content_types": ["application/json", "audio/wav"],
85
- "resources_endpoint": "/api/resources",
86
- "specs_endpoint": "/api/specs",
87
  "limits": {
88
  "max_concurrent_requests": 1,
89
  "max_queue_size": 4,
@@ -105,23 +104,6 @@ def _get_runtime_specs():
105
  }
106
 
107
 
108
- # ---------------------------------------------------------------------------
109
- # FastAPI application with discovery routes
110
- # ---------------------------------------------------------------------------
111
-
112
- api = FastAPI(title=API_SPECS["name"], version=API_SPECS["version"])
113
-
114
-
115
- @api.get("/api/resources")
116
- def resources():
117
- return JSONResponse({"resources": API_RESOURCES})
118
-
119
-
120
- @api.get("/api/specs")
121
- def specs():
122
- return JSONResponse({**API_SPECS, "runtime": _get_runtime_specs()})
123
-
124
-
125
  # ---------------------------------------------------------------------------
126
  # Model cache
127
  # ---------------------------------------------------------------------------
@@ -219,21 +201,42 @@ with gr.Blocks(title="Respite API") as demo:
219
 
220
 
221
  # ---------------------------------------------------------------------------
222
- # Patch launch() so the HF Spaces runner picks up our FastAPI routes.
223
  #
224
- # The Gradio SDK runner calls demo.launch() directly, which normally creates
225
- # its own FastAPI app. By intercepting that call we inject our routes so
226
- # /api/resources and /api/specs are served alongside the Gradio UI.
227
  # ---------------------------------------------------------------------------
228
 
229
  demo.queue(max_size=4, default_concurrency_limit=1)
230
 
231
- _original_launch = demo.launch
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
 
 
 
233
 
234
- def _patched_launch(*args, **kwargs):
235
- kwargs.setdefault("app_kwargs", {})["app"] = api
236
- return _original_launch(*args, **kwargs)
237
 
 
238
 
239
- demo.launch = _patched_launch
 
7
  import torchaudio
8
  import gradio as gr
9
  import spaces
 
10
  from fastapi.responses import JSONResponse
11
  from einops import rearrange
12
  from huggingface_hub import login
 
78
  "name": "Respite API",
79
  "version": "1.0.0",
80
  "description": "General-purpose AI API server with audio generation capabilities.",
81
+ "base_path": "/respite",
82
  "authentication": "none",
83
  "content_types": ["application/json", "audio/wav"],
84
+ "resources_endpoint": "/respite/resources",
85
+ "specs_endpoint": "/respite/specs",
86
  "limits": {
87
  "max_concurrent_requests": 1,
88
  "max_queue_size": 4,
 
104
  }
105
 
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  # ---------------------------------------------------------------------------
108
  # Model cache
109
  # ---------------------------------------------------------------------------
 
201
 
202
 
203
  # ---------------------------------------------------------------------------
204
+ # API discovery endpoints
205
  #
206
+ # Use /respite/ prefix instead of /api/ to avoid collision with Gradio's
207
+ # internal /api proxy which intercepts all /api/* requests in the
208
+ # sdk:gradio Spaces runtime.
209
  # ---------------------------------------------------------------------------
210
 
211
  demo.queue(max_size=4, default_concurrency_limit=1)
212
 
213
+ # These decorators run at import time. demo.app is the FastAPI instance
214
+ # underlying the Gradio Blocks. Routes registered here will be served
215
+ # alongside the Gradio UI once the server starts.
216
+ # NOTE: demo.app is created lazily by Gradio, so we use a startup hook
217
+ # to register routes after the server is ready.
218
+ import threading
219
+
220
+ def _register_routes():
221
+ # Wait for demo.app to be available (created during launch)
222
+ import time
223
+ for _ in range(30):
224
+ if hasattr(demo, "app") and demo.app is not None:
225
+ break
226
+ time.sleep(1)
227
+
228
+ if not hasattr(demo, "app") or demo.app is None:
229
+ _log("Warning: demo.app not available, API routes not registered")
230
+ return
231
 
232
+ @demo.app.get("/respite/resources")
233
+ def resources():
234
+ return JSONResponse({"resources": API_RESOURCES})
235
 
236
+ @demo.app.get("/respite/specs")
237
+ def specs():
238
+ return JSONResponse({**API_SPECS, "runtime": _get_runtime_specs()})
239
 
240
+ _log("API routes registered at /respite/resources and /respite/specs")
241
 
242
+ threading.Thread(target=_register_routes, daemon=True).start()