File size: 5,257 Bytes
2f00f43 af6cd33 236d464 2f00f43 af6cd33 236d464 af6cd33 236d464 af6cd33 2f00f43 af6cd33 6b3f603 af6cd33 2f00f43 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | import axios from "axios";
// ββ Backend configuration ββββββββββββββββββββββββββββββββββββββββββββββββββββ
// If running in the browser, we default to the current origin
const CURRENT_ORIGIN = typeof window !== "undefined" ? window.location.origin : "";
// Option A: Traditional FastAPI backend
const BACKEND_URL = process.env.REACT_APP_BACKEND_URL || CURRENT_ORIGIN;
// Option B: Hugging Face Spaces Gradio backend
// If we are on a .hf.space domain, we default to using Gradio
const isHFSpace = typeof window !== "undefined" && window.location.hostname.endsWith(".hf.space");
const HF_SPACE_URL = process.env.REACT_APP_HF_SPACE_URL || (isHFSpace ? CURRENT_ORIGIN : "");
// When HF_SPACE_URL is set, the frontend routes all calls through Gradio's
// /api/<fn_name> REST endpoints instead of the FastAPI /api/* routes.
const useGradio = !!HF_SPACE_URL && isHFSpace;
// ββ Axios instance for FastAPI mode ββββββββββββββββββββββββββββββββββββββββββ
export const API = `${BACKEND_URL}/api`;
export const api = axios.create({ baseURL: API, timeout: 180000 });
// ββ Gradio API caller ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Gradio exposes each function as a POST endpoint at /api/<api_name>
// Request body: { data: [...args] }
// Response body: { data: [...outputs] }
async function gradioCall(fnName, ...args) {
const url = `${HF_SPACE_URL}/api/${fnName}`;
const resp = await axios.post(url, { data: args }, { timeout: 180000 });
// Gradio returns { data: [output1, output2, ...] }
// Our functions return a single JSON string β parse it
const raw = resp.data?.data?.[0];
if (typeof raw === "string") {
try {
return JSON.parse(raw);
} catch {
return raw;
}
}
return raw;
}
// ββ Unified API adapter βββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Drop-in replacement: every page keeps calling `forgesight.getMetrics()` etc.
// Under the hood it routes to either FastAPI or Gradio.
export const forgesight = {
// GET /api/ β health
async health() {
if (useGradio) return gradioCall("health");
const { data } = await api.get("/");
return data;
},
// POST /api/inspections
async createInspection({ image_base64, notes, product_spec, source }) {
if (useGradio) {
return gradioCall("inspect", image_base64, notes || "", product_spec || "", source || "upload");
}
const { data } = await api.post("/inspections", { image_base64, notes, product_spec, source });
return data;
},
// GET /api/inspections
async listInspections(limit = 50) {
if (useGradio) return gradioCall("list_inspections", limit);
const { data } = await api.get("/inspections", { params: { limit } });
return data;
},
// GET /api/inspections/:id
async getInspection(id) {
if (useGradio) return gradioCall("get_inspection", id);
const { data } = await api.get(`/inspections/${id}`);
return data;
},
// GET /api/metrics
async getMetrics() {
if (useGradio) return gradioCall("metrics");
const { data } = await api.get("/metrics");
return data;
},
// GET /api/telemetry
async getTelemetry() {
if (useGradio) return gradioCall("telemetry");
const { data } = await api.get("/telemetry");
return data;
},
// GET /api/blueprint
async getBlueprint() {
if (useGradio) return gradioCall("blueprint");
const { data } = await api.get("/blueprint");
return data;
},
// GET /api/journal
async listJournal() {
if (useGradio) return gradioCall("journal_list");
const { data } = await api.get("/journal");
return data;
},
// POST /api/journal
async createJournal({ title, body, tags }) {
if (useGradio) {
// Gradio version takes tags as comma-separated string
const tagsStr = Array.isArray(tags) ? tags.join(", ") : tags || "";
return gradioCall("journal_create", title, body, tagsStr);
}
const { data } = await api.post("/journal", { title, body, tags });
return data;
},
// POST /api/journal/seed
async seedJournal() {
if (useGradio) {
// Gradio auto-seeds on journal_list; no-op here
return { seeded: 0, reason: "auto-seeded via journal_list" };
}
const { data } = await api.post("/journal/seed");
return data;
},
};
// ββ Utility βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
export const fileToBase64 = (file) =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const str = reader.result;
const comma = str.indexOf(",");
resolve(comma >= 0 ? str.slice(comma + 1) : str);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
|