omnidiag / frontend /src /api.js
yahyoha's picture
fix(auth): use absolute API_BASE URLs for auth and admin endpoints
5c11c77
Raw
History Blame Contribute Delete
3.16 kB
export const API_BASE = import.meta.env.VITE_API_BASE || 'https://yahyoha-omnidiag.hf.space';
/** Default timeout for API requests (ms). HF Spaces cold starts can take 60-120s. */
const REQUEST_TIMEOUT_MS = 120_000;
/**
* OmniDiag API client.
* Call api.setToken(token) after login so all subsequent requests are authenticated.
*/
class OmniDiagApi {
constructor(baseUrl = API_BASE) {
this.baseUrl = baseUrl.replace(/\/+$/, '');
this._token = null;
}
/** Set the JWT token β€” called by AuthContext after login */
setToken(token) {
this._token = token;
}
/** Build auth header if a token is available */
_authHeader() {
return this._token ? { Authorization: `Bearer ${this._token}` } : {};
}
async _fetch(path, options = {}, timeoutMs = REQUEST_TIMEOUT_MS) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
const url = `${this.baseUrl}${path}`;
try {
const res = await fetch(url, {
headers: {
'Content-Type': 'application/json',
...this._authHeader(),
...options.headers,
},
signal: controller.signal,
...options,
});
if (!res.ok) {
const body = await res.json().catch(() => ({}));
const msg = body?.detail?.error || body?.detail || res.statusText;
throw new Error(msg);
}
return res.json();
} catch (err) {
if (err.name === 'AbortError') {
throw new Error(
'The diagnostic engine is waking up β€” this can take a minute or two on the first scan of the day. Please try again.'
);
}
throw err;
} finally {
clearTimeout(timer);
}
}
/** GET / β€” health check */
health() {
return this._fetch('/');
}
/** GET /api/v4/diseases β€” list registered diseases */
listDiseases() {
return this._fetch('/api/v4/diseases');
}
/** GET /api/v4/{disease}/schema */
getSchema(disease) {
return this._fetch(`/api/v4/${disease}/schema`);
}
/** POST /api/v4/{disease}/predict */
predict(disease, patientData) {
return this._fetch(`/api/v4/${disease}/predict`, {
method: 'POST',
body: JSON.stringify(patientData),
});
}
/** POST /api/v4/{disease}/explain */
explain(disease, patientData) {
return this._fetch(`/api/v4/${disease}/explain`, {
method: 'POST',
body: JSON.stringify(patientData),
});
}
/** POST /api/v4/{disease}/counterfactuals */
counterfactuals(disease, patientData) {
return this._fetch(`/api/v4/${disease}/counterfactuals`, {
method: 'POST',
body: JSON.stringify(patientData),
});
}
/** POST /api/v4/generate-report */
generateReport(payload) {
return this._fetch('/api/v4/generate-report', {
method: 'POST',
body: JSON.stringify(payload),
});
}
/** POST /api/v4/parse-notes */
parseNotes(note, useBert = false) {
return this._fetch('/api/v4/parse-notes', {
method: 'POST',
body: JSON.stringify({ note, use_bert: useBert }),
});
}
}
export const api = new OmniDiagApi();
export default OmniDiagApi;