parina004
Initial HF deployment
e6efe7e
Raw
History Blame Contribute Delete
3.11 kB
// api.js
// Shared API client — all fetch calls to the FastAPI backend go through here.
const _h = window.location.hostname;
const API_BASE = (_h === 'localhost' || _h === '127.0.0.1' || _h === '::1' || _h === '')
? 'http://127.0.0.1:8000' // local dev
: 'https://parina13-synthsenses-api.hf.space'; // production
/**
* Wakes the Render server if it has spun down (free tier cold start ~30-90s).
* Updates the loading message while waiting.
*/
async function _wakeServer() {
const TIMEOUT_MS = 90_000;
const POLL_MS = 3_000;
const deadline = Date.now() + TIMEOUT_MS;
// Try once immediately — if server is up this returns fast
try {
const res = await fetch(`${API_BASE}/health`, { method: 'GET' });
if (res.ok) return;
} catch (_) { /* server is sleeping, start polling */ }
// Show "waking up" message if server didn't respond immediately
const loadingEl = document.getElementById('loading');
const loadingP = loadingEl ? loadingEl.querySelector('p') : null;
if (loadingP) loadingP.textContent = 'Waking up server (first request may take ~30s)…';
while (Date.now() < deadline) {
await new Promise(r => setTimeout(r, POLL_MS));
try {
const res = await fetch(`${API_BASE}/health`, { method: 'GET' });
if (res.ok) {
if (loadingP) loadingP.textContent = 'Analysing video…';
return;
}
} catch (_) { /* still booting */ }
}
throw new Error('Server took too long to wake up. Please try again in a moment.');
}
/**
* POST /analyze/synthetic
* @param {File} videoFile
* @returns {Promise<{label, confidence, prob_ai, prob_deepfake}>}
*/
async function analyzeSynthetic(videoFile) {
await _wakeServer();
const form = new FormData();
form.append('video', videoFile);
const res = await fetch(`${API_BASE}/analyze/synthetic`, {
method: 'POST',
body: form,
});
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }));
throw new Error(err.detail || 'Synthetic detection failed.');
}
return res.json();
}
/**
* POST /analyze/virality
* @param {File} videoFile
* @param {{title, post_hour, post_day, tag_count, user_caption, user_hashtags}} meta
* @returns {Promise<{virality_score, label, probability, top_features, features, explanation}>}
*/
async function analyzeVirality(videoFile, meta) {
await _wakeServer();
const form = new FormData();
form.append('video', videoFile);
form.append('title', meta.title ?? '');
form.append('post_hour', meta.post_hour ?? 12);
form.append('post_day', meta.post_day ?? 1);
form.append('tag_count', meta.tag_count ?? 5);
form.append('user_caption', meta.user_caption ?? '');
form.append('user_hashtags', meta.user_hashtags ?? '');
const res = await fetch(`${API_BASE}/analyze/virality`, {
method: 'POST',
body: form,
});
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }));
throw new Error(err.detail || 'Virality prediction failed.');
}
return res.json();
}