Michael Rabinovich commited on
Commit
4e86f82
·
1 Parent(s): f2f35be

app+requirements: pin Gradio 5 + gradio_leaderboard, auto-refresh now works

Browse files

Step 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.

Files changed (2) hide show
  1. app.py +11 -36
  2. requirements.txt +11 -1
app.py CHANGED
@@ -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
- # Gradio 6's gr.Dataframe identity-checks its component id and
54
- # short-circuits the diff when the new value's shape + column
55
- # structure look unchanged, even though the row data differs.
56
- # That swallows updates from every= on the Dataframe AND from
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())
requirements.txt CHANGED
@@ -1,4 +1,14 @@
1
- gradio==6.14.0
 
 
 
 
 
 
 
 
 
 
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