fix: make React API base URL dynamic to avoid 404s on HF Spaces
Browse files- frontend/src/lib/api.js +9 -6
- hf_space/build/asset-manifest.json +3 -3
- hf_space/build/index.html +1 -1
- hf_space/build/static/js/{main.d7054bd7.js → main.3aab7668.js} +0 -0
- hf_space/build/static/js/{main.d7054bd7.js.LICENSE.txt → main.3aab7668.js.LICENSE.txt} +0 -0
- hf_space/build/static/js/{main.d7054bd7.js.map → main.3aab7668.js.map} +0 -0
- scratch/test_amd_token_param.py +29 -0
- scratch/test_amd_urls.py +31 -0
frontend/src/lib/api.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
| 1 |
import axios from "axios";
|
| 2 |
|
| 3 |
// ── Backend configuration ────────────────────────────────────────────────────
|
| 4 |
-
//
|
| 5 |
-
const
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
// Option B: Hugging Face Spaces Gradio backend
|
| 8 |
-
//
|
| 9 |
-
|
| 10 |
-
const HF_SPACE_URL = process.env.REACT_APP_HF_SPACE_URL;
|
| 11 |
|
| 12 |
// When HF_SPACE_URL is set, the frontend routes all calls through Gradio's
|
| 13 |
// /api/<fn_name> REST endpoints instead of the FastAPI /api/* routes.
|
| 14 |
-
const useGradio = !!HF_SPACE_URL;
|
| 15 |
|
| 16 |
// ── Axios instance for FastAPI mode ──────────────────────────────────────────
|
| 17 |
export const API = `${BACKEND_URL}/api`;
|
|
|
|
| 1 |
import axios from "axios";
|
| 2 |
|
| 3 |
// ── Backend configuration ────────────────────────────────────────────────────
|
| 4 |
+
// If running in the browser, we default to the current origin
|
| 5 |
+
const CURRENT_ORIGIN = typeof window !== "undefined" ? window.location.origin : "";
|
| 6 |
+
|
| 7 |
+
// Option A: Traditional FastAPI backend
|
| 8 |
+
const BACKEND_URL = process.env.REACT_APP_BACKEND_URL || CURRENT_ORIGIN;
|
| 9 |
|
| 10 |
// Option B: Hugging Face Spaces Gradio backend
|
| 11 |
+
// If we are on a .hf.space domain, we default to using Gradio
|
| 12 |
+
const isHFSpace = typeof window !== "undefined" && window.location.hostname.endsWith(".hf.space");
|
| 13 |
+
const HF_SPACE_URL = process.env.REACT_APP_HF_SPACE_URL || (isHFSpace ? CURRENT_ORIGIN : "");
|
| 14 |
|
| 15 |
// When HF_SPACE_URL is set, the frontend routes all calls through Gradio's
|
| 16 |
// /api/<fn_name> REST endpoints instead of the FastAPI /api/* routes.
|
| 17 |
+
const useGradio = !!HF_SPACE_URL && isHFSpace;
|
| 18 |
|
| 19 |
// ── Axios instance for FastAPI mode ──────────────────────────────────────────
|
| 20 |
export const API = `${BACKEND_URL}/api`;
|
hf_space/build/asset-manifest.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
| 1 |
{
|
| 2 |
"files": {
|
| 3 |
"main.css": "/static/css/main.9a119fc2.css",
|
| 4 |
-
"main.js": "/static/js/main.
|
| 5 |
"static/js/977.5a4c08f0.chunk.js": "/static/js/977.5a4c08f0.chunk.js",
|
| 6 |
"static/js/455.3bef4cb2.chunk.js": "/static/js/455.3bef4cb2.chunk.js",
|
| 7 |
"index.html": "/index.html",
|
| 8 |
"main.9a119fc2.css.map": "/static/css/main.9a119fc2.css.map",
|
| 9 |
-
"main.
|
| 10 |
"977.5a4c08f0.chunk.js.map": "/static/js/977.5a4c08f0.chunk.js.map",
|
| 11 |
"455.3bef4cb2.chunk.js.map": "/static/js/455.3bef4cb2.chunk.js.map"
|
| 12 |
},
|
| 13 |
"entrypoints": [
|
| 14 |
"static/css/main.9a119fc2.css",
|
| 15 |
-
"static/js/main.
|
| 16 |
]
|
| 17 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"files": {
|
| 3 |
"main.css": "/static/css/main.9a119fc2.css",
|
| 4 |
+
"main.js": "/static/js/main.3aab7668.js",
|
| 5 |
"static/js/977.5a4c08f0.chunk.js": "/static/js/977.5a4c08f0.chunk.js",
|
| 6 |
"static/js/455.3bef4cb2.chunk.js": "/static/js/455.3bef4cb2.chunk.js",
|
| 7 |
"index.html": "/index.html",
|
| 8 |
"main.9a119fc2.css.map": "/static/css/main.9a119fc2.css.map",
|
| 9 |
+
"main.3aab7668.js.map": "/static/js/main.3aab7668.js.map",
|
| 10 |
"977.5a4c08f0.chunk.js.map": "/static/js/977.5a4c08f0.chunk.js.map",
|
| 11 |
"455.3bef4cb2.chunk.js.map": "/static/js/455.3bef4cb2.chunk.js.map"
|
| 12 |
},
|
| 13 |
"entrypoints": [
|
| 14 |
"static/css/main.9a119fc2.css",
|
| 15 |
+
"static/js/main.3aab7668.js"
|
| 16 |
]
|
| 17 |
}
|
hf_space/build/index.html
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Ras Ali Labs"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/><link href="https://fonts.googleapis.com/css2?family=Inter:wght@600&display=swap" rel="stylesheet"/><title>ForgeSight · Multimodal QC Copilot · AMD MI300X</title><script>window.addEventListener("error",function(e){e.error instanceof DOMException&&"DataCloneError"===e.error.name&&e.message&&e.message.includes("PerformanceServerTiming")&&(e.stopImmediatePropagation(),e.preventDefault())},!0)</script><script defer="defer" src="/static/js/main.
|
|
|
|
| 1 |
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Ras Ali Labs"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/><link href="https://fonts.googleapis.com/css2?family=Inter:wght@600&display=swap" rel="stylesheet"/><title>ForgeSight · Multimodal QC Copilot · AMD MI300X</title><script>window.addEventListener("error",function(e){e.error instanceof DOMException&&"DataCloneError"===e.error.name&&e.message&&e.message.includes("PerformanceServerTiming")&&(e.stopImmediatePropagation(),e.preventDefault())},!0)</script><script defer="defer" src="/static/js/main.3aab7668.js"></script><link href="/static/css/main.9a119fc2.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e,t){var r,s,o,i;t.__SV||(window.posthog=t,t._i=[],t.init=function(n,a,p){function c(e,t){var r=t.split(".");2==r.length&&(e=e[r[0]],t=r[1]),e[t]=function(){e.push([t].concat(Array.prototype.slice.call(arguments,0)))}}(o=e.createElement("script")).type="text/javascript",o.crossOrigin="anonymous",o.async=!0,o.src=a.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(i=e.getElementsByTagName("script")[0]).parentNode.insertBefore(o,i);var g=t;for(void 0!==p?g=t[p]=[]:p="posthog",g.people=g.people||[],g.toString=function(e){var t="posthog";return"posthog"!==p&&(t+="."+p),e||(t+=" (stub)"),t},g.people.toString=function(){return g.toString(1)+".people (stub)"},r="init me ws ys ps bs capture je Di ks register register_once register_for_session unregister unregister_for_session Ps getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSurveysLoaded onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey canRenderSurveyAsync identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty Es $s createPersonProfile Is opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing Ss debug xs getPageViewId captureTraceFeedback captureTraceMetric".split(" "),s=0;s<r.length;s++)c(g,r[s]);t._i.push([n,a,p])},t.__SV=1)}(document,window.posthog||[]),posthog.init("phc_xAvL2Iq4tFmANRE7kzbKwaSqp1HJjN7x48s3vr0CMjs",{api_host:"https://us.i.posthog.com",person_profiles:"identified_only",session_recording:{recordCrossOriginIframes:!0,capturePerformance:!1}})</script></body></html>
|
hf_space/build/static/js/{main.d7054bd7.js → main.3aab7668.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
hf_space/build/static/js/{main.d7054bd7.js.LICENSE.txt → main.3aab7668.js.LICENSE.txt}
RENAMED
|
File without changes
|
hf_space/build/static/js/{main.d7054bd7.js.map → main.3aab7668.js.map}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scratch/test_amd_token_param.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import httpx
|
| 2 |
+
import asyncio
|
| 3 |
+
|
| 4 |
+
async def test():
|
| 5 |
+
token = "DiPipPSZoxb96rcrP7X+B0N5mTTEzxU/ziesgI/Z2NPo9xPKM"
|
| 6 |
+
|
| 7 |
+
urls = [
|
| 8 |
+
f"http://165.245.137.80/proxy/8000/v1/models?token={token}",
|
| 9 |
+
f"http://165.245.137.80/proxy/8001/v1/models?token={token}",
|
| 10 |
+
f"http://165.245.137.80/v1/models?token={token}",
|
| 11 |
+
]
|
| 12 |
+
|
| 13 |
+
for url in urls:
|
| 14 |
+
print(f"Testing {url}...")
|
| 15 |
+
try:
|
| 16 |
+
async with httpx.AsyncClient(timeout=5.0) as client:
|
| 17 |
+
resp = await client.get(url)
|
| 18 |
+
print(f" Status: {resp.status_code}")
|
| 19 |
+
if resp.status_code == 200:
|
| 20 |
+
print(f" SUCCESS!")
|
| 21 |
+
print(f" Data: {resp.text[:200]}")
|
| 22 |
+
else:
|
| 23 |
+
print(f" Body: {resp.text[:100]}")
|
| 24 |
+
except Exception as e:
|
| 25 |
+
print(f" Error: {e}")
|
| 26 |
+
print("-" * 20)
|
| 27 |
+
|
| 28 |
+
if __name__ == "__main__":
|
| 29 |
+
asyncio.run(test())
|
scratch/test_amd_urls.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import httpx
|
| 2 |
+
import asyncio
|
| 3 |
+
|
| 4 |
+
async def test():
|
| 5 |
+
token = "DiPipPSZoxb96rcrP7X+B0N5mTTEzxU/ziesgI/Z2NPo9xPKM"
|
| 6 |
+
headers = {"Authorization": f"Bearer {token}"}
|
| 7 |
+
|
| 8 |
+
urls = [
|
| 9 |
+
"http://165.245.137.80/v1/models",
|
| 10 |
+
"http://165.245.137.80:8000/v1/models",
|
| 11 |
+
"http://165.245.137.80/proxy/8000/v1/models",
|
| 12 |
+
"http://165.245.137.80/proxy/8888/v1/models"
|
| 13 |
+
]
|
| 14 |
+
|
| 15 |
+
for url in urls:
|
| 16 |
+
print(f"Testing {url}...")
|
| 17 |
+
try:
|
| 18 |
+
async with httpx.AsyncClient(timeout=5.0) as client:
|
| 19 |
+
resp = await client.get(url, headers=headers)
|
| 20 |
+
print(f" Status: {resp.status_code}")
|
| 21 |
+
if resp.status_code == 200:
|
| 22 |
+
print(f" SUCCESS!")
|
| 23 |
+
print(f" Data: {resp.text[:200]}")
|
| 24 |
+
else:
|
| 25 |
+
print(f" Body: {resp.text[:100]}")
|
| 26 |
+
except Exception as e:
|
| 27 |
+
print(f" Error: {e}")
|
| 28 |
+
print("-" * 20)
|
| 29 |
+
|
| 30 |
+
if __name__ == "__main__":
|
| 31 |
+
asyncio.run(test())
|