Commit Β·
3f11a0e
1
Parent(s): 7cacbd0
Replace server-side slot-visibility updates with client-side JS
Browse filesGradio 5.25's client rejects gr.Group visibility outputs with "Too many
arguments provided for the endpoint" (500 on /queue/join), even when
isolated in their own .then() step β confirmed via fn_index tracing
that this wasn't session staleness but a real, reproducible bug tied
specifically to Group components as event outputs.
Toggling display on the slot Group's DOM element (by elem_id) via a
fn=None/js= event needs no server round-trip, so there's nothing left
for that validation to reject.
app.py
CHANGED
|
@@ -2474,7 +2474,7 @@ def _make_output_slots(tab_prefix: str) -> tuple:
|
|
| 2474 |
grps, vids, waveforms = [], [], []
|
| 2475 |
for i in range(MAX_SLOTS):
|
| 2476 |
slot_id = f"{tab_prefix}_{i}"
|
| 2477 |
-
with gr.Group(visible=(i == 0)) as g:
|
| 2478 |
vids.append(gr.Video(label=f"Generation {i+1} β Video",
|
| 2479 |
elem_id=f"slot_vid_{slot_id}",
|
| 2480 |
show_download_button=False))
|
|
@@ -2532,11 +2532,6 @@ def _on_video_upload_taro(video_file, num_steps, crossfade_s):
|
|
| 2532 |
return gr.update(maximum=max_s, value=min(1, max_s))
|
| 2533 |
|
| 2534 |
|
| 2535 |
-
def _update_slot_visibility(n):
|
| 2536 |
-
n = int(n)
|
| 2537 |
-
return [gr.update(visible=(i < n)) for i in range(MAX_SLOTS)]
|
| 2538 |
-
|
| 2539 |
-
|
| 2540 |
def _btn_generating():
|
| 2541 |
"""Disable a Generate button and show a busy label. Chained as the first
|
| 2542 |
.click() step so it fires immediately, before the (possibly slow) generate
|
|
@@ -2586,6 +2581,22 @@ _GLOBAL_JS = """
|
|
| 2586 |
if (window._wf_global_listener) return; // already registered
|
| 2587 |
window._wf_global_listener = true;
|
| 2588 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2589 |
// ββ ZeroGPU quota attribution ββ
|
| 2590 |
// HF Spaces run inside an iframe on huggingface.co. Gradio's own JS client
|
| 2591 |
// gets ZeroGPU auth headers (x-zerogpu-token, x-zerogpu-uuid) by sending a
|
|
@@ -3017,7 +3028,7 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3017 |
taro_btn = gr.Button("Generate", variant="primary")
|
| 3018 |
|
| 3019 |
with gr.Column(scale=1):
|
| 3020 |
-
(
|
| 3021 |
taro_slot_waves) = _make_output_slots("taro")
|
| 3022 |
|
| 3023 |
# Hidden regen plumbing β render=False so no DOM element is created,
|
|
@@ -3034,9 +3045,10 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3034 |
outputs=[taro_samples],
|
| 3035 |
)
|
| 3036 |
taro_samples.change(
|
| 3037 |
-
fn=
|
| 3038 |
inputs=[taro_samples],
|
| 3039 |
-
outputs=
|
|
|
|
| 3040 |
)
|
| 3041 |
|
| 3042 |
def _run_taro(video, seed, cfg, steps, mode, cf_dur, cf_db, n):
|
|
@@ -3065,9 +3077,10 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3065 |
taro_cf_dur, taro_cf_db, taro_samples],
|
| 3066 |
outputs=taro_slot_vids + taro_slot_waves,
|
| 3067 |
).then(
|
| 3068 |
-
fn=
|
| 3069 |
inputs=[taro_samples],
|
| 3070 |
-
outputs=
|
|
|
|
| 3071 |
).then(
|
| 3072 |
fn=_btn_ready,
|
| 3073 |
inputs=None,
|
|
@@ -3101,7 +3114,7 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3101 |
mma_btn = gr.Button("Generate", variant="primary")
|
| 3102 |
|
| 3103 |
with gr.Column(scale=1):
|
| 3104 |
-
(
|
| 3105 |
mma_slot_waves) = _make_output_slots("mma")
|
| 3106 |
|
| 3107 |
# Hidden regen plumbing β render=False so no DOM element is created,
|
|
@@ -3110,9 +3123,10 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3110 |
mma_regen_state = gr.Textbox(value="", render=False)
|
| 3111 |
|
| 3112 |
mma_samples.change(
|
| 3113 |
-
fn=
|
| 3114 |
inputs=[mma_samples],
|
| 3115 |
-
outputs=
|
|
|
|
| 3116 |
)
|
| 3117 |
|
| 3118 |
def _run_mmaudio(video, prompt, neg, seed, cfg, steps, cf_dur, cf_db, n):
|
|
@@ -3129,9 +3143,10 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3129 |
mma_cfg, mma_steps, mma_cf_dur, mma_cf_db, mma_samples],
|
| 3130 |
outputs=mma_slot_vids + mma_slot_waves,
|
| 3131 |
).then(
|
| 3132 |
-
fn=
|
| 3133 |
inputs=[mma_samples],
|
| 3134 |
-
outputs=
|
|
|
|
| 3135 |
).then(
|
| 3136 |
fn=_btn_ready,
|
| 3137 |
inputs=None,
|
|
@@ -3164,7 +3179,7 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3164 |
hf_btn = gr.Button("Generate", variant="primary")
|
| 3165 |
|
| 3166 |
with gr.Column(scale=1):
|
| 3167 |
-
(
|
| 3168 |
hf_slot_waves) = _make_output_slots("hf")
|
| 3169 |
|
| 3170 |
# Hidden regen plumbing β render=False so no DOM element is created,
|
|
@@ -3173,9 +3188,10 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3173 |
hf_regen_state = gr.Textbox(value="", render=False)
|
| 3174 |
|
| 3175 |
hf_samples.change(
|
| 3176 |
-
fn=
|
| 3177 |
inputs=[hf_samples],
|
| 3178 |
-
outputs=
|
|
|
|
| 3179 |
)
|
| 3180 |
|
| 3181 |
def _run_hunyuan(video, prompt, neg, seed, guidance, steps, size, cf_dur, cf_db, n):
|
|
@@ -3192,9 +3208,10 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
|
|
| 3192 |
hf_guidance, hf_steps, hf_size, hf_cf_dur, hf_cf_db, hf_samples],
|
| 3193 |
outputs=hf_slot_vids + hf_slot_waves,
|
| 3194 |
).then(
|
| 3195 |
-
fn=
|
| 3196 |
inputs=[hf_samples],
|
| 3197 |
-
outputs=
|
|
|
|
| 3198 |
).then(
|
| 3199 |
fn=_btn_ready,
|
| 3200 |
inputs=None,
|
|
|
|
| 2474 |
grps, vids, waveforms = [], [], []
|
| 2475 |
for i in range(MAX_SLOTS):
|
| 2476 |
slot_id = f"{tab_prefix}_{i}"
|
| 2477 |
+
with gr.Group(visible=(i == 0), elem_id=f"slot_grp_{slot_id}") as g:
|
| 2478 |
vids.append(gr.Video(label=f"Generation {i+1} β Video",
|
| 2479 |
elem_id=f"slot_vid_{slot_id}",
|
| 2480 |
show_download_button=False))
|
|
|
|
| 2532 |
return gr.update(maximum=max_s, value=min(1, max_s))
|
| 2533 |
|
| 2534 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2535 |
def _btn_generating():
|
| 2536 |
"""Disable a Generate button and show a busy label. Chained as the first
|
| 2537 |
.click() step so it fires immediately, before the (possibly slow) generate
|
|
|
|
| 2581 |
if (window._wf_global_listener) return; // already registered
|
| 2582 |
window._wf_global_listener = true;
|
| 2583 |
|
| 2584 |
+
// Toggle output-slot visibility by directly flipping display on the slot
|
| 2585 |
+
// Group's DOM element. This used to be a server round-trip (a .then() that
|
| 2586 |
+
// returned gr.update(visible=...) for each Group), but Gradio 5.25's client
|
| 2587 |
+
// rejects Group-visibility outputs with "Too many arguments provided for
|
| 2588 |
+
// the endpoint" (500 on /queue/join) even when isolated in their own step β
|
| 2589 |
+
// doing it client-side sidesteps that bug entirely, no server call needed.
|
| 2590 |
+
window._updateSlotVisibility = function(prefix, n) {
|
| 2591 |
+
let i = 0;
|
| 2592 |
+
while (true) {
|
| 2593 |
+
const el = document.getElementById('slot_grp_' + prefix + '_' + i);
|
| 2594 |
+
if (!el) break;
|
| 2595 |
+
el.style.display = (i < n) ? '' : 'none';
|
| 2596 |
+
i++;
|
| 2597 |
+
}
|
| 2598 |
+
};
|
| 2599 |
+
|
| 2600 |
// ββ ZeroGPU quota attribution ββ
|
| 2601 |
// HF Spaces run inside an iframe on huggingface.co. Gradio's own JS client
|
| 2602 |
// gets ZeroGPU auth headers (x-zerogpu-token, x-zerogpu-uuid) by sending a
|
|
|
|
| 3028 |
taro_btn = gr.Button("Generate", variant="primary")
|
| 3029 |
|
| 3030 |
with gr.Column(scale=1):
|
| 3031 |
+
(_, taro_slot_vids,
|
| 3032 |
taro_slot_waves) = _make_output_slots("taro")
|
| 3033 |
|
| 3034 |
# Hidden regen plumbing β render=False so no DOM element is created,
|
|
|
|
| 3045 |
outputs=[taro_samples],
|
| 3046 |
)
|
| 3047 |
taro_samples.change(
|
| 3048 |
+
fn=None,
|
| 3049 |
inputs=[taro_samples],
|
| 3050 |
+
outputs=[],
|
| 3051 |
+
js="(n) => window._updateSlotVisibility('taro', n)",
|
| 3052 |
)
|
| 3053 |
|
| 3054 |
def _run_taro(video, seed, cfg, steps, mode, cf_dur, cf_db, n):
|
|
|
|
| 3077 |
taro_cf_dur, taro_cf_db, taro_samples],
|
| 3078 |
outputs=taro_slot_vids + taro_slot_waves,
|
| 3079 |
).then(
|
| 3080 |
+
fn=None,
|
| 3081 |
inputs=[taro_samples],
|
| 3082 |
+
outputs=[],
|
| 3083 |
+
js="(n) => window._updateSlotVisibility('taro', n)",
|
| 3084 |
).then(
|
| 3085 |
fn=_btn_ready,
|
| 3086 |
inputs=None,
|
|
|
|
| 3114 |
mma_btn = gr.Button("Generate", variant="primary")
|
| 3115 |
|
| 3116 |
with gr.Column(scale=1):
|
| 3117 |
+
(_, mma_slot_vids,
|
| 3118 |
mma_slot_waves) = _make_output_slots("mma")
|
| 3119 |
|
| 3120 |
# Hidden regen plumbing β render=False so no DOM element is created,
|
|
|
|
| 3123 |
mma_regen_state = gr.Textbox(value="", render=False)
|
| 3124 |
|
| 3125 |
mma_samples.change(
|
| 3126 |
+
fn=None,
|
| 3127 |
inputs=[mma_samples],
|
| 3128 |
+
outputs=[],
|
| 3129 |
+
js="(n) => window._updateSlotVisibility('mma', n)",
|
| 3130 |
)
|
| 3131 |
|
| 3132 |
def _run_mmaudio(video, prompt, neg, seed, cfg, steps, cf_dur, cf_db, n):
|
|
|
|
| 3143 |
mma_cfg, mma_steps, mma_cf_dur, mma_cf_db, mma_samples],
|
| 3144 |
outputs=mma_slot_vids + mma_slot_waves,
|
| 3145 |
).then(
|
| 3146 |
+
fn=None,
|
| 3147 |
inputs=[mma_samples],
|
| 3148 |
+
outputs=[],
|
| 3149 |
+
js="(n) => window._updateSlotVisibility('mma', n)",
|
| 3150 |
).then(
|
| 3151 |
fn=_btn_ready,
|
| 3152 |
inputs=None,
|
|
|
|
| 3179 |
hf_btn = gr.Button("Generate", variant="primary")
|
| 3180 |
|
| 3181 |
with gr.Column(scale=1):
|
| 3182 |
+
(_, hf_slot_vids,
|
| 3183 |
hf_slot_waves) = _make_output_slots("hf")
|
| 3184 |
|
| 3185 |
# Hidden regen plumbing β render=False so no DOM element is created,
|
|
|
|
| 3188 |
hf_regen_state = gr.Textbox(value="", render=False)
|
| 3189 |
|
| 3190 |
hf_samples.change(
|
| 3191 |
+
fn=None,
|
| 3192 |
inputs=[hf_samples],
|
| 3193 |
+
outputs=[],
|
| 3194 |
+
js="(n) => window._updateSlotVisibility('hf', n)",
|
| 3195 |
)
|
| 3196 |
|
| 3197 |
def _run_hunyuan(video, prompt, neg, seed, guidance, steps, size, cf_dur, cf_db, n):
|
|
|
|
| 3208 |
hf_guidance, hf_steps, hf_size, hf_cf_dur, hf_cf_db, hf_samples],
|
| 3209 |
outputs=hf_slot_vids + hf_slot_waves,
|
| 3210 |
).then(
|
| 3211 |
+
fn=None,
|
| 3212 |
inputs=[hf_samples],
|
| 3213 |
+
outputs=[],
|
| 3214 |
+
js="(n) => window._updateSlotVisibility('hf', n)",
|
| 3215 |
).then(
|
| 3216 |
fn=_btn_ready,
|
| 3217 |
inputs=None,
|