Spaces:
Running on Zero
Running on Zero
Commit ·
03cbad9
1
Parent(s): 8b3b191
Add HF token input for ZeroGPU Pro quota on regen
Browse filesUsers can paste their HF token in the Settings accordion so that
segment regen calls use Authorization: Bearer <token> — the documented
way for ZeroGPU to attribute quota to a Pro account. Falls back to
x-ip-token relay if no token is provided. Quota now correctly debits
the logged-in user's Pro pool instead of the shared anonymous pool.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
app.py
CHANGED
|
@@ -2133,13 +2133,26 @@ _GLOBAL_JS = """
|
|
| 2133 |
console.warn('[fireRegen] fn_index not found for api_name:', apiName);
|
| 2134 |
return;
|
| 2135 |
}
|
| 2136 |
-
//
|
| 2137 |
-
//
|
| 2138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2139 |
var regenHeaders = {'Content-Type': 'application/json'};
|
| 2140 |
-
if (
|
| 2141 |
-
|
| 2142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2143 |
method: 'POST',
|
| 2144 |
credentials: 'include',
|
| 2145 |
headers: regenHeaders,
|
|
@@ -2150,18 +2163,23 @@ _GLOBAL_JS = """
|
|
| 2150 |
event_data: null,
|
| 2151 |
trigger_id: null
|
| 2152 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2153 |
});
|
| 2154 |
-
}
|
| 2155 |
-
|
| 2156 |
-
|
| 2157 |
-
|
| 2158 |
-
|
| 2159 |
-
|
| 2160 |
-
|
| 2161 |
-
if (lbl) lbl.textContent = 'Error — see console';
|
| 2162 |
-
var sb = document.getElementById('wf_statusbar_' + slot_id);
|
| 2163 |
-
if (sb) { sb.style.color = '#e05252'; sb.textContent = '\u26a0 Request failed: ' + e.message; }
|
| 2164 |
-
});
|
| 2165 |
}
|
| 2166 |
|
| 2167 |
// Subscribe to Gradio SSE stream for an event and apply outputs to DOM.
|
|
@@ -2341,6 +2359,19 @@ _GLOBAL_JS = """
|
|
| 2341 |
"""
|
| 2342 |
|
| 2343 |
with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) as demo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2344 |
gr.Markdown(
|
| 2345 |
"# Generate Audio for Video\n"
|
| 2346 |
"Choose a model and upload a video to generate synchronized audio.\n\n"
|
|
|
|
| 2133 |
console.warn('[fireRegen] fn_index not found for api_name:', apiName);
|
| 2134 |
return;
|
| 2135 |
}
|
| 2136 |
+
// Build auth headers for the regen call.
|
| 2137 |
+
// Prefer a user-supplied HF token (Authorization: Bearer) which is the
|
| 2138 |
+
// documented way for ZeroGPU to attribute quota to a logged-in Pro account.
|
| 2139 |
+
// Fall back to the x-ip-token relay approach if no HF token is provided.
|
| 2140 |
+
var userHfToken = '';
|
| 2141 |
+
var hfTokenEl = document.getElementById('hf_token_input');
|
| 2142 |
+
if (hfTokenEl) { var inp = hfTokenEl.querySelector('input,textarea'); if (inp) userHfToken = (inp.value || '').trim(); }
|
| 2143 |
+
|
| 2144 |
+
var _doRegen = function(ipToken) {
|
| 2145 |
var regenHeaders = {'Content-Type': 'application/json'};
|
| 2146 |
+
if (userHfToken) {
|
| 2147 |
+
regenHeaders['Authorization'] = 'Bearer ' + userHfToken;
|
| 2148 |
+
console.log('[fireRegen] using HF token for Pro quota attribution');
|
| 2149 |
+
} else if (ipToken) {
|
| 2150 |
+
regenHeaders['x-ip-token'] = ipToken;
|
| 2151 |
+
console.log('[fireRegen] using fresh x-ip-token, len:', ipToken.length);
|
| 2152 |
+
} else {
|
| 2153 |
+
console.warn('[fireRegen] no auth available, regen may use anonymous quota');
|
| 2154 |
+
}
|
| 2155 |
+
fetch('/gradio_api/queue/join', {
|
| 2156 |
method: 'POST',
|
| 2157 |
credentials: 'include',
|
| 2158 |
headers: regenHeaders,
|
|
|
|
| 2163 |
event_data: null,
|
| 2164 |
trigger_id: null
|
| 2165 |
})
|
| 2166 |
+
}).then(function(r) { return r.json(); }).then(function(j) {
|
| 2167 |
+
if (!j.event_id) { console.error('[fireRegen] no event_id:', j); return; }
|
| 2168 |
+
console.log('[fireRegen] queued, event_id:', j.event_id);
|
| 2169 |
+
_listenAndApply(j.event_id, slot_id, seg_idx, _preRegenWaveHtml, _preRegenVideoSrc);
|
| 2170 |
+
}).catch(function(e) {
|
| 2171 |
+
console.error('[fireRegen] fetch error:', e);
|
| 2172 |
+
if (lbl) lbl.textContent = 'Error — see console';
|
| 2173 |
+
var sb = document.getElementById('wf_statusbar_' + slot_id);
|
| 2174 |
+
if (sb) { sb.style.color = '#e05252'; sb.textContent = '\u26a0 Request failed: ' + e.message; }
|
| 2175 |
});
|
| 2176 |
+
};
|
| 2177 |
+
// If user provided HF token, skip x-ip-token relay (token is sufficient)
|
| 2178 |
+
if (userHfToken) {
|
| 2179 |
+
_doRegen('');
|
| 2180 |
+
} else {
|
| 2181 |
+
_fetchIpToken().then(_doRegen);
|
| 2182 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2183 |
}
|
| 2184 |
|
| 2185 |
// Subscribe to Gradio SSE stream for an event and apply outputs to DOM.
|
|
|
|
| 2359 |
"""
|
| 2360 |
|
| 2361 |
with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) as demo:
|
| 2362 |
+
with gr.Accordion("⚙️ Settings (optional)", open=False):
|
| 2363 |
+
gr.Markdown(
|
| 2364 |
+
"**HF Token** — Paste your [Hugging Face token](https://huggingface.co/settings/tokens) here so that "
|
| 2365 |
+
"segment regeneration uses your own ZeroGPU quota (PRO = 25 min/day) instead of the shared free pool. "
|
| 2366 |
+
"The token is stored only in your browser and never sent anywhere except the Space's own API."
|
| 2367 |
+
)
|
| 2368 |
+
hf_token_input = gr.Textbox(
|
| 2369 |
+
label="Hugging Face Token (optional)",
|
| 2370 |
+
placeholder="hf_...",
|
| 2371 |
+
type="password",
|
| 2372 |
+
elem_id="hf_token_input",
|
| 2373 |
+
max_lines=1,
|
| 2374 |
+
)
|
| 2375 |
gr.Markdown(
|
| 2376 |
"# Generate Audio for Video\n"
|
| 2377 |
"Choose a model and upload a video to generate synchronized audio.\n\n"
|