ghmk commited on
Commit
c0aa9ee
·
1 Parent(s): 89d20a8

fix: replace gr.DataFrame with gr.HTML to fix Gradio 6.12 crash

Browse files

gr.DataFrame with column_widths triggers a circular property getter
(groupedColumnMode) in Gradio 6.12 causing RangeError: Maximum call
stack size exceeded, followed by repeated TypeErrors in the Dataframe
Svelte component. This freezes the entire UI after Walk results load.

Fix: render the active-features table as plain HTML via gr.HTML().
No JavaScript tabular library involved — no crash, no freeze.
Also removes the now-unused pandas dependency.

Files changed (2) hide show
  1. app.py +44 -20
  2. requirements.txt +0 -1
app.py CHANGED
@@ -13,7 +13,6 @@ import subprocess
13
  from pathlib import Path
14
 
15
  import gradio as gr
16
- import pandas as pd
17
 
18
  # Add demo dir to path so utils is importable both locally and on HF Spaces
19
  sys.path.insert(0, str(Path(__file__).parent))
@@ -107,11 +106,47 @@ def binary_status_md() -> str:
107
  # ---------------------------------------------------------------------------
108
  # Tab 1 — Walk Explorer
109
  # ---------------------------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  def do_walk(vindex_path, prompt, layer_from, layer_to, top_k):
111
  if not prompt.strip():
112
- return pd.DataFrame(), "Enter a prompt above."
113
  if not vindex_path.strip():
114
- return pd.DataFrame(), "Enter a vindex path."
115
 
116
  layers_arg = f"{int(layer_from)}-{int(layer_to)}"
117
  rc, out, err = run_larql(
@@ -124,17 +159,16 @@ def do_walk(vindex_path, prompt, layer_from, layer_to, top_k):
124
  )
125
  combined = (out + "\n" + err).strip()
126
  if rc != 0:
127
- return pd.DataFrame(), f"**Error:**\n```\n{combined}\n```"
128
 
129
  rows = parse_walk_output(combined)
130
  if not rows:
131
- return pd.DataFrame(), f"No features returned.\n\nRaw output:\n```\n{combined}\n```"
132
 
133
- df = pd.DataFrame(rows)
134
- # Summary footer from last line of output
135
  summary = [l for l in combined.splitlines() if l.startswith("Walk:")]
136
  status = summary[-1] if summary else ""
137
- return df, f"✓ {status}"
138
 
139
 
140
  def update_layer_max(vindex_path):
@@ -408,18 +442,8 @@ with gr.Blocks(title="LARQL Explorer") as demo:
408
  )
409
 
410
  walk_status = gr.Markdown("")
411
- walk_table = gr.DataFrame(
412
- label="Active features",
413
- wrap=True,
414
- column_widths=["80px", "90px", "80px", "110px", "140px", "80px", "auto"],
415
- )
416
- gr.Markdown(
417
- "_💡 **Tip:** If clicking other tabs stops working after running Walk, "
418
- "refresh the page (F5) and navigate to the desired tab first. "
419
- "This is a Gradio 6.12 interaction bug that only appears after "
420
- "the feature table is populated._",
421
- visible=True,
422
- )
423
 
424
  walk_btn.click(
425
  do_walk,
 
13
  from pathlib import Path
14
 
15
  import gradio as gr
 
16
 
17
  # Add demo dir to path so utils is importable both locally and on HF Spaces
18
  sys.path.insert(0, str(Path(__file__).parent))
 
106
  # ---------------------------------------------------------------------------
107
  # Tab 1 — Walk Explorer
108
  # ---------------------------------------------------------------------------
109
+ def _rows_to_html(rows: list[dict]) -> str:
110
+ """Render walk result rows as a styled HTML table (avoids Gradio 6.12 DataFrame bug)."""
111
+ if not rows:
112
+ return ""
113
+ cols = list(rows[0].keys())
114
+ th_style = (
115
+ "padding:6px 10px;text-align:left;border-bottom:2px solid #444;"
116
+ "font-size:0.82rem;color:#aaa;white-space:nowrap;"
117
+ )
118
+ td_style = "padding:5px 10px;border-bottom:1px solid #2a2a2a;font-size:0.82rem;vertical-align:top;"
119
+ tbl = (
120
+ '<div style="overflow-x:auto;border-radius:8px;border:1px solid #333;">'
121
+ '<table style="width:100%;border-collapse:collapse;background:#1a1a1a;">'
122
+ "<thead><tr>"
123
+ )
124
+ for c in cols:
125
+ tbl += f'<th style="{th_style}">{c}</th>'
126
+ tbl += "</tr></thead><tbody>"
127
+ for i, row in enumerate(rows):
128
+ bg = "#1e1e1e" if i % 2 == 0 else "#222"
129
+ tbl += f'<tr style="background:{bg}">'
130
+ for c in cols:
131
+ val = row[c]
132
+ cell_style = td_style
133
+ if c == "Direction":
134
+ color = "#4ade80" if "excites" in str(val) else "#f87171"
135
+ cell_style += f"color:{color};font-weight:600;"
136
+ elif c == "Gate":
137
+ color = "#4ade80" if float(val) > 0 else "#f87171"
138
+ cell_style += f"color:{color};"
139
+ tbl += f'<td style="{cell_style}">{val}</td>'
140
+ tbl += "</tr>"
141
+ tbl += "</tbody></table></div>"
142
+ return tbl
143
+
144
+
145
  def do_walk(vindex_path, prompt, layer_from, layer_to, top_k):
146
  if not prompt.strip():
147
+ return "", "Enter a prompt above."
148
  if not vindex_path.strip():
149
+ return "", "Enter a vindex path."
150
 
151
  layers_arg = f"{int(layer_from)}-{int(layer_to)}"
152
  rc, out, err = run_larql(
 
159
  )
160
  combined = (out + "\n" + err).strip()
161
  if rc != 0:
162
+ return "", f"**Error:**\n```\n{combined}\n```"
163
 
164
  rows = parse_walk_output(combined)
165
  if not rows:
166
+ return "", f"No features returned.\n\nRaw output:\n```\n{combined}\n```"
167
 
168
+ html = _rows_to_html(rows)
 
169
  summary = [l for l in combined.splitlines() if l.startswith("Walk:")]
170
  status = summary[-1] if summary else ""
171
+ return html, f"✓ {status}"
172
 
173
 
174
  def update_layer_max(vindex_path):
 
442
  )
443
 
444
  walk_status = gr.Markdown("")
445
+ gr.Markdown("**Active features**", elem_classes=["label-md"])
446
+ walk_table = gr.HTML(value="")
 
 
 
 
 
 
 
 
 
 
447
 
448
  walk_btn.click(
449
  do_walk,
requirements.txt CHANGED
@@ -1,3 +1,2 @@
1
  gradio>=6.0.0
2
- pandas>=2.0.0
3
  huggingface_hub>=0.20.0
 
1
  gradio>=6.0.0
 
2
  huggingface_hub>=0.20.0