app+requirements: pin Gradio 5 + gradio_leaderboard, auto-refresh now works
Browse filesStep 6 (E) chunk 5, take 2. The Gradio 6.14 gr.Dataframe component
silently swallows row updates after the first render: server-side
load_leaderboard fires every N seconds (logged: "Loaded 11 rows
from Hub" on each tick) but the rendered DOM never picks the new
rows up. Confirmed with a local row-growing fixture (load_leaderboard
monkey-patched to return N+1 rows on each call); the server fired
10 times, the DOM stuck on the first call's row count.
Tried in order, all failed against the local fixture:
- gr.Dataframe(every=10, value=callable)
- gr.Timer(10).tick(outputs=gr.Dataframe)
- manual Refresh button click
- @gr .render(inputs=[gr.State, gr.State], key=f"...-{tick}")
- @gr .render(inputs=[hidden gr.Textbox], key=f"...-{tick}")
- streaming generator on app.load (first yield delivered; every
subsequent yield ignored client-side)
What actually works: pin to Gradio 5 (latest 5.50.0) and use the
gradio_leaderboard.Leaderboard custom component, which has its own
update path and is the component every shipping HF leaderboard
(open-llm-leaderboard, DABstep, bigcodebench) actually uses.
gradio_leaderboard pins gradio<6.0,>=4.0 so there is no Gradio 6
build today; revisit when one ships AND the underlying Dataframe-
update bug is fixed upstream.
Local verification: row-growing fixture goes 5 -> 10 in the DOM
across 50s (one new row per 10s Timer tick), screenshot confirmed.
Bonus: Leaderboard component ships a free search box across
submission_name + submitter_name; nothing else changes
behaviourally (still our load_leaderboard producing a pandas
DataFrame, still our status/score formatters, still our
auto-refresh cadence + manual Refresh button).
Outstanding follow-up: file a minimal-repro gradio issue against
gr.Dataframe in 6.14 so this pin gets revisited when a fix lands.
- app.py +11 -36
- requirements.txt +11 -1
|
@@ -6,9 +6,9 @@ Read path lives in :mod:`leaderboard`. Submit-tab validation lives in
|
|
| 6 |
from __future__ import annotations
|
| 7 |
|
| 8 |
import logging
|
| 9 |
-
import time
|
| 10 |
|
| 11 |
import gradio as gr
|
|
|
|
| 12 |
|
| 13 |
from leaderboard import (
|
| 14 |
HF_DATA_REPO,
|
|
@@ -50,43 +50,13 @@ with gr.Blocks(title="CADGenBench Leaderboard") as app:
|
|
| 50 |
)
|
| 51 |
|
| 52 |
with gr.Tab("Leaderboard"):
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
# gr.Timer().tick(outputs=df_view) AND from a manual refresh
|
| 58 |
-
# button click. The fix is @gr.render with a `key=` that
|
| 59 |
-
# changes on every tick: Gradio tears down and rebuilds the
|
| 60 |
-
# component subtree in place, picking up the fresh value.
|
| 61 |
-
#
|
| 62 |
-
# The fetch happens once per tick in `_refresh_table` (server
|
| 63 |
-
# side) and the result rides on gr.State to all subscribers,
|
| 64 |
-
# so N concurrent viewers don't cause N HTTPS GETs per tick.
|
| 65 |
-
table_state = gr.State(value=load_leaderboard())
|
| 66 |
-
tick_state = gr.State(value=0)
|
| 67 |
-
|
| 68 |
-
@gr.render(inputs=[table_state, tick_state])
|
| 69 |
-
def render_leaderboard(df, t: int) -> None:
|
| 70 |
-
gr.Dataframe(
|
| 71 |
-
value=df,
|
| 72 |
-
interactive=False,
|
| 73 |
-
wrap=True,
|
| 74 |
-
label="Results (sorted by aggregate CAD score)",
|
| 75 |
-
key=f"leaderboard-df-{t}",
|
| 76 |
-
)
|
| 77 |
-
|
| 78 |
-
def _refresh_table():
|
| 79 |
-
# ms-resolution so rapid clicks always increment the key.
|
| 80 |
-
return load_leaderboard(), int(time.time() * 1000)
|
| 81 |
-
|
| 82 |
-
auto_refresh_timer = gr.Timer(10)
|
| 83 |
-
auto_refresh_timer.tick(
|
| 84 |
-
fn=_refresh_table, outputs=[table_state, tick_state],
|
| 85 |
)
|
| 86 |
refresh_btn = gr.Button("Refresh", size="sm")
|
| 87 |
-
refresh_btn.click(
|
| 88 |
-
fn=_refresh_table, outputs=[table_state, tick_state],
|
| 89 |
-
)
|
| 90 |
|
| 91 |
with gr.Tab("Submit"):
|
| 92 |
gr.Markdown(
|
|
@@ -131,6 +101,11 @@ to publish the resulting row on the public leaderboard.
|
|
| 131 |
with gr.Tab("About"):
|
| 132 |
gr.Markdown(ABOUT_MD)
|
| 133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
if __name__ == "__main__":
|
| 136 |
app.launch(theme=gr.themes.Soft())
|
|
|
|
| 6 |
from __future__ import annotations
|
| 7 |
|
| 8 |
import logging
|
|
|
|
| 9 |
|
| 10 |
import gradio as gr
|
| 11 |
+
from gradio_leaderboard import Leaderboard
|
| 12 |
|
| 13 |
from leaderboard import (
|
| 14 |
HF_DATA_REPO,
|
|
|
|
| 50 |
)
|
| 51 |
|
| 52 |
with gr.Tab("Leaderboard"):
|
| 53 |
+
df_view = Leaderboard(
|
| 54 |
+
value=load_leaderboard(),
|
| 55 |
+
search_columns=["submission_name", "submitter_name"],
|
| 56 |
+
label="Results (sorted by aggregate CAD score)",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
)
|
| 58 |
refresh_btn = gr.Button("Refresh", size="sm")
|
| 59 |
+
refresh_btn.click(fn=load_leaderboard, outputs=df_view)
|
|
|
|
|
|
|
| 60 |
|
| 61 |
with gr.Tab("Submit"):
|
| 62 |
gr.Markdown(
|
|
|
|
| 101 |
with gr.Tab("About"):
|
| 102 |
gr.Markdown(ABOUT_MD)
|
| 103 |
|
| 104 |
+
# gradio_leaderboard.Leaderboard handles its own update path
|
| 105 |
+
# cleanly; bind a Timer to push a fresh dataframe every 10 seconds.
|
| 106 |
+
auto_refresh_timer = gr.Timer(10)
|
| 107 |
+
auto_refresh_timer.tick(fn=load_leaderboard, outputs=df_view)
|
| 108 |
+
|
| 109 |
|
| 110 |
if __name__ == "__main__":
|
| 111 |
app.launch(theme=gr.themes.Soft())
|
|
@@ -1,4 +1,14 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
pandas>=2.0
|
| 3 |
huggingface_hub>=0.27.0
|
| 4 |
datasets>=3.0
|
|
|
|
| 1 |
+
# Pinned to Gradio 5.x because gr.Dataframe in Gradio 6.14 silently
|
| 2 |
+
# drops all updates after the first render: server-side load_leaderboard
|
| 3 |
+
# runs (and yields under demo.load), but the rendered DOM never picks
|
| 4 |
+
# up the new rows. Reproduced locally with a row-growing fixture, then
|
| 5 |
+
# verified to work cleanly with gradio_leaderboard.Leaderboard on
|
| 6 |
+
# Gradio 5. The reference HF leaderboards (open-llm-leaderboard,
|
| 7 |
+
# DABstep, bigcodebench) all run on this stack. Revisit once a
|
| 8 |
+
# Gradio 6-compatible gradio_leaderboard ships AND the underlying
|
| 9 |
+
# Dataframe-update bug is fixed upstream.
|
| 10 |
+
gradio==5.50.0
|
| 11 |
+
gradio-leaderboard==0.0.14
|
| 12 |
pandas>=2.0
|
| 13 |
huggingface_hub>=0.27.0
|
| 14 |
datasets>=3.0
|