ha251 commited on
Commit
4c42c06
·
verified ·
1 Parent(s): c7ef4e9

Update miniapp_leaderboard.py

Browse files
Files changed (1) hide show
  1. miniapp_leaderboard.py +82 -75
miniapp_leaderboard.py CHANGED
@@ -162,7 +162,6 @@ def _load_entries_df() -> pd.DataFrame:
162
  for c in NUMERIC_COLS:
163
  df[c] = pd.to_numeric(df[c], errors="coerce")
164
 
165
- # 默认按提交时间倒序
166
  df = df.sort_values(by=["Submitted at"], ascending=False, kind="stable")
167
  return df
168
 
@@ -177,9 +176,6 @@ def _parse_hf_created_at(created_at: str) -> datetime.datetime | None:
177
 
178
 
179
  def _check_user_eligibility(username: str) -> tuple[bool, str]:
180
- """
181
- - Must be older than ~4 months (>= 120 days)
182
- """
183
  try:
184
  r = requests.get(f"https://huggingface.co/api/users/{username}/overview", timeout=10)
185
  r.raise_for_status()
@@ -192,8 +188,7 @@ def _check_user_eligibility(username: str) -> tuple[bool, str]:
192
  now = datetime.datetime.now(datetime.timezone.utc)
193
  if dt.tzinfo is None:
194
  dt = dt.replace(tzinfo=datetime.timezone.utc)
195
- age_days = (now - dt).days
196
- if age_days < 120:
197
  return False, "Account must be older than 4 months to submit."
198
  return True, ""
199
  except Exception:
@@ -238,11 +233,11 @@ def _render_leaderboard_html(df: pd.DataFrame, sort_col: str, sort_dir: str) ->
238
  if col:
239
  arrow = ""
240
  if col == sort_col:
241
- arrow = " " if sort_dir == "asc" else " "
242
  al = " left" if align_left else ""
243
- return f'<th class="h clickable{al} {cls}" data-col="{_html.escape(col)}">{_html.escape(label)}{arrow}</th>'
244
  al = " left" if align_left else ""
245
- return f'<th class="h{al} {cls}">{_html.escape(label)}</th>'
246
 
247
  trs = []
248
  for _, r in df.iterrows():
@@ -250,30 +245,30 @@ def _render_leaderboard_html(df: pd.DataFrame, sort_col: str, sort_dir: str) ->
250
  for c in DISPLAY_ORDER:
251
  val = _fmt_cell(r.get(c, ""))
252
  if c == "Model name":
253
- tds.append(f'<td class="cell model">{_html.escape(val)}</td>')
254
  else:
255
- tds.append(f'<td class="cell num">{_html.escape(val)}</td>')
256
- trs.append("<tr class='r'>" + "".join(tds) + "</tr>")
257
 
258
  return f"""
259
- <div class="lb-card">
260
- <div class="lb-scroll">
261
- <table class="lb" id="lb_table">
262
  <thead>
263
- <tr class="t1">
264
  {th("Avg. (%)", "Avg", cls="avg")}
265
  {th("Model", "Model name", align_left=True, cls="model")}
266
- <th class="h group" colspan="9">Pass Rate (%)</th>
267
  </tr>
268
- <tr class="t2">
269
- <th class="h"></th>
270
- <th class="h"></th>
271
- <th class="h group" colspan="3">Difficulty</th>
272
- <th class="h group" colspan="6">Domain</th>
273
  </tr>
274
- <tr class="t3">
275
- <th class="h"></th>
276
- <th class="h"></th>
277
  {th("Easy", "Easy")}
278
  {th("Mid", "Mid")}
279
  {th("Hard", "Hard")}
@@ -345,7 +340,6 @@ def submit(
345
  if _submitted_today(submitter):
346
  return "You have already submitted today. Please try again tomorrow.", render_lb(search_text, sort_col, sort_dir)
347
 
348
- # api_key collected but NOT stored
349
  now = datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z"
350
  nonce = uuid.uuid4().hex[:8]
351
  safe_user = _slug(submitter)
@@ -388,81 +382,96 @@ def submit(
388
 
389
 
390
  CSS = r"""
391
- /* Blocks 内容更贴边、更像网站 */
392
  .gradio-container { max-width: 100% !important; }
393
- #page { padding: 18px 18px 28px 18px; }
394
 
395
- /* 顶部一行 */
396
- #topbar { display:flex; align-items:center; justify-content:space-between; gap:12px; }
397
- #titleline { font-weight: 700; font-size: 20px; line-height: 1; }
398
  #searchbox { width: 280px; }
399
  #searchbox label { display:none !important; }
400
  #searchbox textarea, #searchbox input {
401
- height: 36px !important;
402
- border-radius: 10px !important;
403
- border: 1px solid rgba(0,0,0,.10) !important;
404
- background: rgba(0,0,0,.02) !important;
405
  box-shadow: none !important;
406
  }
407
- #searchbox textarea::placeholder, #searchbox input::placeholder { color: rgba(0,0,0,.35); }
408
 
409
- /* 卡片式表格 */
410
- .lb-card{
411
  width: 100%;
412
- border: 1px solid rgba(0,0,0,.08);
413
- border-radius: 14px;
414
- background: white;
415
  }
416
- .lb-scroll { width: 100%; overflow-x: auto; }
417
- table.lb { width: 100%; border-collapse: separate; border-spacing: 0; min-width: 1100px; }
418
- table.lb thead th.h{
 
 
 
 
 
 
 
419
  font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial;
420
- font-weight: 700;
421
  font-size: 13px;
422
- color: rgba(0,0,0,.75);
423
  padding: 10px 12px;
424
  text-align: center;
425
- border-bottom: 1px solid rgba(0,0,0,.08);
426
- background: rgba(0,0,0,.02);
 
427
  white-space: nowrap;
428
  }
429
- table.lb thead tr.t1 th { border-bottom: 1px solid rgba(0,0,0,.10); }
430
- table.lb thead tr.t2 th { background: rgba(0,0,0,.015); }
431
- table.lb thead th.left{ text-align:left; }
432
- table.lb thead th.group{
433
- font-weight: 800;
434
- color: rgba(0,0,0,.80);
435
- }
436
 
437
- table.lb tbody td.cell{
 
438
  font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial;
439
  font-size: 13px;
 
440
  padding: 10px 12px;
441
- border-bottom: 1px solid rgba(0,0,0,.06);
442
- background: white;
 
443
  }
444
- table.lb tbody tr.r:hover td { background: rgba(0,0,0,.02); }
445
- td.num { text-align:right; }
446
- td.model { text-align:left; min-width: 280px; }
447
- th.avg, td.avg { min-width: 90px; }
448
 
449
- th.clickable { cursor: pointer; user-select: none; }
450
- th.clickable:hover { background: rgba(0,0,0,.05); }
 
451
 
452
- /* 提交:全宽卡片 */
453
  #submit_card{
454
  width: 100%;
455
- border: 1px solid rgba(0,0,0,.08);
456
- border-radius: 14px;
457
- padding: 14px;
458
- background: white;
 
 
 
 
 
 
459
  }
460
- #submit_card .prose { margin: 0 0 10px 0; color: rgba(0,0,0,.72); font-size: 13px; }
461
  """
462
 
463
  with gr.Blocks(title=f"{APP_NAME} leaderboard") as demo:
464
  with gr.Column(elem_id="page"):
465
- # 顶部栏:左标题,右搜索 + 刷新(同一行,不显眼)
466
  with gr.Row(elem_id="topbar"):
467
  gr.Markdown(f"<div id='titleline'>{APP_NAME} leaderboard</div>")
468
  with gr.Row():
@@ -482,7 +491,6 @@ with gr.Blocks(title=f"{APP_NAME} leaderboard") as demo:
482
 
483
  clicked_col = gr.Textbox(visible=False, elem_id="clicked_col")
484
 
485
- # JS:表头点击 -> 写入隐藏 textbox -> 触发 change
486
  gr.HTML(
487
  """
488
  <script>
@@ -523,11 +531,11 @@ with gr.Blocks(title=f"{APP_NAME} leaderboard") as demo:
523
  outputs=[sort_col, sort_dir, lb_html],
524
  )
525
 
526
- # 提交:全宽卡片 + 两列输入
527
  gr.HTML(
528
  """
529
  <div id="submit_card">
530
- <div class="prose">
531
  <b>Submission</b> — Submit <b>Model API URL</b> and <b>API key</b> only.
532
  Requires login (Spaces). One submission per user per day. Account must be older than 4 months.
533
  API key will <b>not</b> be stored.
@@ -536,7 +544,6 @@ with gr.Blocks(title=f"{APP_NAME} leaderboard") as demo:
536
  """
537
  )
538
 
539
- # 用 Column/Row 做“占满横向”的提交表单
540
  with gr.Column():
541
  with gr.Row():
542
  model_api = gr.Textbox(label="Model API URL", placeholder="https://...", scale=3)
 
162
  for c in NUMERIC_COLS:
163
  df[c] = pd.to_numeric(df[c], errors="coerce")
164
 
 
165
  df = df.sort_values(by=["Submitted at"], ascending=False, kind="stable")
166
  return df
167
 
 
176
 
177
 
178
  def _check_user_eligibility(username: str) -> tuple[bool, str]:
 
 
 
179
  try:
180
  r = requests.get(f"https://huggingface.co/api/users/{username}/overview", timeout=10)
181
  r.raise_for_status()
 
188
  now = datetime.datetime.now(datetime.timezone.utc)
189
  if dt.tzinfo is None:
190
  dt = dt.replace(tzinfo=datetime.timezone.utc)
191
+ if (now - dt).days < 120:
 
192
  return False, "Account must be older than 4 months to submit."
193
  return True, ""
194
  except Exception:
 
233
  if col:
234
  arrow = ""
235
  if col == sort_col:
236
+ arrow = " " if sort_dir == "asc" else " "
237
  al = " left" if align_left else ""
238
+ return f'<th class="th clickable{al} {cls}" data-col="{_html.escape(col)}">{_html.escape(label)}{arrow}</th>'
239
  al = " left" if align_left else ""
240
+ return f'<th class="th{al} {cls}">{_html.escape(label)}</th>'
241
 
242
  trs = []
243
  for _, r in df.iterrows():
 
245
  for c in DISPLAY_ORDER:
246
  val = _fmt_cell(r.get(c, ""))
247
  if c == "Model name":
248
+ tds.append(f'<td class="td model">{_html.escape(val)}</td>')
249
  else:
250
+ tds.append(f'<td class="td num">{_html.escape(val)}</td>')
251
+ trs.append("<tr class='tr'>" + "".join(tds) + "</tr>")
252
 
253
  return f"""
254
+ <div class="table-wrap">
255
+ <div class="table-scroll">
256
+ <table class="table" id="lb_table">
257
  <thead>
258
+ <tr class="r1">
259
  {th("Avg. (%)", "Avg", cls="avg")}
260
  {th("Model", "Model name", align_left=True, cls="model")}
261
+ <th class="th group" colspan="9">Pass Rate (%)</th>
262
  </tr>
263
+ <tr class="r2">
264
+ <th class="th"></th>
265
+ <th class="th"></th>
266
+ <th class="th group" colspan="3">Difficulty</th>
267
+ <th class="th group" colspan="6">Domain</th>
268
  </tr>
269
+ <tr class="r3">
270
+ <th class="th"></th>
271
+ <th class="th"></th>
272
  {th("Easy", "Easy")}
273
  {th("Mid", "Mid")}
274
  {th("Hard", "Hard")}
 
340
  if _submitted_today(submitter):
341
  return "You have already submitted today. Please try again tomorrow.", render_lb(search_text, sort_col, sort_dir)
342
 
 
343
  now = datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z"
344
  nonce = uuid.uuid4().hex[:8]
345
  safe_user = _slug(submitter)
 
382
 
383
 
384
  CSS = r"""
385
+ /* 全宽 */
386
  .gradio-container { max-width: 100% !important; }
387
+ #page { padding: 16px; }
388
 
389
+ /* 顶部一行:搜索弱化 */
390
+ #topbar { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom: 10px; }
391
+ #titleline { font-weight: 700; font-size: 18px; }
392
  #searchbox { width: 280px; }
393
  #searchbox label { display:none !important; }
394
  #searchbox textarea, #searchbox input {
395
+ height: 34px !important;
396
+ border-radius: 8px !important;
397
+ border: 1px solid #e5e7eb !important;
398
+ background: #fff !important;
399
  box-shadow: none !important;
400
  }
401
+ #searchbox textarea::placeholder, #searchbox input::placeholder { color: #9ca3af; }
402
 
403
+ /* 表格:浅灰分割线风格 */
404
+ .table-wrap{
405
  width: 100%;
406
+ border: 1px solid #e5e7eb;
407
+ border-radius: 8px;
408
+ background: #fff;
409
  }
410
+ .table-scroll{ width: 100%; overflow-x: auto; }
411
+ table.table{
412
+ width: 100%;
413
+ border-collapse: separate;
414
+ border-spacing: 0;
415
+ min-width: 1100px;
416
+ }
417
+
418
+ /* 表头 */
419
+ th.th{
420
  font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial;
421
+ font-weight: 600;
422
  font-size: 13px;
423
+ color: #111827;
424
  padding: 10px 12px;
425
  text-align: center;
426
+ background: #f9fafb;
427
+ border-bottom: 1px solid #e5e7eb;
428
+ border-right: 1px solid #e5e7eb;
429
  white-space: nowrap;
430
  }
431
+ thead tr.r1 th.th, thead tr.r2 th.th { background: #f9fafb; }
432
+ thead tr.r3 th.th { background: #ffffff; }
433
+
434
+ th.th.left{ text-align:left; }
435
+ th.group{ color:#374151; font-weight:600; }
436
+ th.th:last-child{ border-right: none; }
 
437
 
438
+ /* body */
439
+ td.td{
440
  font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial;
441
  font-size: 13px;
442
+ color: #111827;
443
  padding: 10px 12px;
444
+ border-bottom: 1px solid #f0f1f3;
445
+ border-right: 1px solid #f0f1f3;
446
+ background: #fff;
447
  }
448
+ td.td:last-child{ border-right: none; }
449
+ td.num{ text-align:right; }
450
+ td.model{ text-align:left; min-width: 280px; }
451
+ tr.tr:hover td.td{ background: #fafafa; }
452
 
453
+ /* 可点击排序 */
454
+ th.clickable{ cursor:pointer; user-select:none; }
455
+ th.clickable:hover{ background:#f3f4f6; }
456
 
457
+ /* 提交:全宽 */
458
  #submit_card{
459
  width: 100%;
460
+ border: 1px solid #e5e7eb;
461
+ border-radius: 8px;
462
+ padding: 12px;
463
+ background: #fff;
464
+ margin-top: 14px;
465
+ }
466
+ #submit_card .hint{
467
+ margin: 0 0 10px 0;
468
+ color: #6b7280;
469
+ font-size: 13px;
470
  }
 
471
  """
472
 
473
  with gr.Blocks(title=f"{APP_NAME} leaderboard") as demo:
474
  with gr.Column(elem_id="page"):
 
475
  with gr.Row(elem_id="topbar"):
476
  gr.Markdown(f"<div id='titleline'>{APP_NAME} leaderboard</div>")
477
  with gr.Row():
 
491
 
492
  clicked_col = gr.Textbox(visible=False, elem_id="clicked_col")
493
 
 
494
  gr.HTML(
495
  """
496
  <script>
 
531
  outputs=[sort_col, sort_dir, lb_html],
532
  )
533
 
534
+ # 提交模块:全宽
535
  gr.HTML(
536
  """
537
  <div id="submit_card">
538
+ <div class="hint">
539
  <b>Submission</b> — Submit <b>Model API URL</b> and <b>API key</b> only.
540
  Requires login (Spaces). One submission per user per day. Account must be older than 4 months.
541
  API key will <b>not</b> be stored.
 
544
  """
545
  )
546
 
 
547
  with gr.Column():
548
  with gr.Row():
549
  model_api = gr.Textbox(label="Model API URL", placeholder="https://...", scale=3)