tytsui commited on
Commit
2a6775f
·
1 Parent(s): 510f3e9
Files changed (2) hide show
  1. app.py +98 -54
  2. src/leaderboard/student_results.py +43 -1
app.py CHANGED
@@ -8,6 +8,7 @@ from huggingface_hub import snapshot_download
8
 
9
  from src.display.css_html_js import custom_css
10
  from src.leaderboard.student_results import (
 
11
  get_group_submission_history,
12
  get_latest_submission,
13
  get_student_leaderboard_df,
@@ -223,18 +224,66 @@ with demo:
223
 
224
  # Tab 3: submission status / history
225
  with gr.TabItem("📥 Submission Status", elem_id="submission-status-tab"):
226
- with gr.Column():
227
- status_group_id_tb = gr.Textbox(label="Group ID", placeholder="Your pure digit on the sheet", scale=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  check_status_btn = gr.Button("Check Submission Status")
229
- status_summary_md = gr.Markdown()
230
- history_df = gr.components.Dataframe(row_count=5)
231
 
232
- def handle_status_check(group_id):
233
- gid = str(group_id).strip()
234
- if not gid:
235
- return "Please enter a Group ID.", pd.DataFrame()
236
 
237
- # Refresh results mirror, but tolerate failures
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  try:
239
  snapshot_download(
240
  repo_id=RESULTS_REPO,
@@ -244,56 +293,51 @@ with demo:
244
  etag_timeout=30,
245
  token=TOKEN,
246
  )
 
 
 
 
 
 
 
 
 
247
  except Exception:
248
  pass
249
 
250
- history = get_group_submission_history(gid)
251
- if history is None or history.empty:
252
- return f"No submissions found for Group ID `{gid}`.", pd.DataFrame()
253
-
254
- # Hide internal/status/error and score/weight columns
255
- cols_to_hide = [
256
- "status",
257
- "Status",
258
- "error",
259
- "Error",
260
- "proj",
261
- "Proj",
262
- "track",
263
- "Track",
264
- "score",
265
- "final_score",
266
- "final score",
267
- "weight",
268
- "weights",
269
- "has_weights",
270
- ]
271
- drop_cols = [c for c in cols_to_hide if c in history.columns]
272
- display_df = history.drop(columns=drop_cols) if drop_cols else history
273
-
274
- # Reorder columns to put group_id and alias at the front (group_id first, then alias)
275
- cols = list(display_df.columns)
276
- if "group_id" in cols and "alias" in cols:
277
- cols.remove("group_id")
278
- cols.remove("alias")
279
- cols = ["group_id", "alias"] + cols
280
- display_df = display_df[cols]
281
- elif "alias" in cols:
282
- cols.remove("alias")
283
- cols = ["alias"] + cols
284
- display_df = display_df[cols]
285
-
286
- summary = (
287
- f"**Group ID**: `{gid}` \n"
288
- f"Total submissions: {len(display_df)} \n"
289
- "Most recent appears first."
290
- )
291
- return summary, display_df
292
 
293
  check_status_btn.click(
294
- handle_status_check,
295
- [status_group_id_tb],
296
- [status_summary_md, history_df],
297
  )
298
 
299
  demo.queue(default_concurrency_limit=40).launch()
 
8
 
9
  from src.display.css_html_js import custom_css
10
  from src.leaderboard.student_results import (
11
+ get_failed_submissions_by_group,
12
  get_group_submission_history,
13
  get_latest_submission,
14
  get_student_leaderboard_df,
 
224
 
225
  # Tab 3: submission status / history
226
  with gr.TabItem("📥 Submission Status", elem_id="submission-status-tab"):
227
+ # Guidelines warning banner
228
+ gr.Markdown(
229
+ """
230
+ ## ⚠️ Important: Read Before Submitting
231
+
232
+ **Please follow the submission guidelines carefully before submitting your code!**
233
+
234
+ Common reasons for failed submissions include:
235
+
236
+ - Missing or incorrectly named files (`model.py`, `preprocess.py`)
237
+
238
+ - Incompatible model architecture or missing dependencies
239
+
240
+ - Runtime errors in your code (check your imports and function signatures)
241
+
242
+ - Incorrect output format from your model
243
+
244
+ **Review the submission requirements** to avoid wasting your submission attempts.
245
+
246
+ ---
247
+
248
+ """,
249
+ elem_classes="markdown-text",
250
+ )
251
+
252
+ # Shared Group ID input at the top
253
+ gr.Markdown("### 🔍 Check Your Submission Status\nEnter your Group ID to view both successful and failed submissions:")
254
+ with gr.Row():
255
+ status_group_id_tb = gr.Textbox(
256
+ label="Group ID",
257
+ placeholder="Your pure digit on the sheet",
258
+ scale=1,
259
+ )
260
+ with gr.Row():
261
  check_status_btn = gr.Button("Check Submission Status")
 
 
262
 
263
+ # Section 1: Successful Submissions
264
+ with gr.Accordion("✅ Successful Submissions", open=True):
265
+ status_result_md = gr.Markdown()
266
+ status_perf_df = gr.components.Dataframe(row_count=1)
267
 
268
+ # Section 2: Failed Submissions
269
+ with gr.Accordion("❌ Failed Submissions", open=True):
270
+ gr.Markdown(
271
+ "*If you have failed submissions, review the error messages below and fix the issues before resubmitting.*"
272
+ )
273
+ failed_result_md = gr.Markdown()
274
+ failed_submissions_df = gr.components.Dataframe(row_count=1)
275
+
276
+ def check_submission_status(group_id: str):
277
+ group_id = (group_id or "").strip()
278
+ if not group_id:
279
+ return (
280
+ "Please enter a valid Group ID.",
281
+ pd.DataFrame(),
282
+ "",
283
+ pd.DataFrame(),
284
+ )
285
+
286
+ # Ensure we have the latest data locally
287
  try:
288
  snapshot_download(
289
  repo_id=RESULTS_REPO,
 
293
  etag_timeout=30,
294
  token=TOKEN,
295
  )
296
+ snapshot_download(
297
+ repo_id=QUEUE_REPO,
298
+ local_dir=EVAL_REQUESTS_PATH,
299
+ repo_type="dataset",
300
+ tqdm_class=None,
301
+ etag_timeout=30,
302
+ token=TOKEN,
303
+ allow_patterns=[f"{PROJ_DIR}/**/request.json"],
304
+ )
305
  except Exception:
306
  pass
307
 
308
+ # Get successful submissions
309
+ submissions_df = get_group_submission_history(group_id)
310
+ if submissions_df is None or submissions_df.empty:
311
+ success_md = f"No successful submissions found for Group ID `{group_id}`."
312
+ success_df = pd.DataFrame()
313
+ else:
314
+ success_md = f"**Total successful submissions**: {len(submissions_df)}\n\nMost recent submission appears first."
315
+ history_rows = []
316
+ for _, sub in submissions_df.iterrows():
317
+ history_rows.append({
318
+ "Alias": sub.get("alias", ""),
319
+ "Timestamp": sub.get("timestamp", ""),
320
+ "Dataset": sub.get("dataset", ""),
321
+ "Accuracy": sub.get("accuracy"),
322
+ "Avg infer (ms)": sub.get("avg_infer_ms"),
323
+ "Total infer (s)": sub.get("total_infer_s"),
324
+ })
325
+ success_df = pd.DataFrame(history_rows)
326
+
327
+ # Get failed submissions
328
+ failed_df = get_failed_submissions_by_group(group_id)
329
+ if failed_df is None or failed_df.empty:
330
+ failed_md = f"No failed submissions found for Group ID `{group_id}`. 🎉"
331
+ failed_df = pd.DataFrame()
332
+ else:
333
+ failed_md = f"**Total failed submissions**: {len(failed_df)}\n\n⚠️ Please review the error messages and fix the issues before resubmitting."
334
+
335
+ return success_md, success_df, failed_md, failed_df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
 
337
  check_status_btn.click(
338
+ check_submission_status,
339
+ inputs=[status_group_id_tb],
340
+ outputs=[status_result_md, status_perf_df, failed_result_md, failed_submissions_df],
341
  )
342
 
343
  demo.queue(default_concurrency_limit=40).launch()
src/leaderboard/student_results.py CHANGED
@@ -5,7 +5,7 @@ from typing import Dict, Optional, Tuple
5
  import numpy as np
6
  import pandas as pd
7
 
8
- from src.envs import EVAL_RESULTS_PATH, PROJ_DIR
9
 
10
 
11
  def _load_all_attempts() -> pd.DataFrame:
@@ -152,3 +152,45 @@ def get_student_status(group_id: str) -> Dict[str, Optional[str]]:
152
  "message": error_msg if status == "FAILED" else "",
153
  "timestamp": latest.get("timestamp"),
154
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  import numpy as np
6
  import pandas as pd
7
 
8
+ from src.envs import EVAL_REQUESTS_PATH, EVAL_RESULTS_PATH, PROJ_DIR
9
 
10
 
11
  def _load_all_attempts() -> pd.DataFrame:
 
152
  "message": error_msg if status == "FAILED" else "",
153
  "timestamp": latest.get("timestamp"),
154
  }
155
+
156
+
157
+ def get_failed_submissions_by_group(group_id: str) -> pd.DataFrame:
158
+ """
159
+ Return all FAILED submissions for a given group_id from the requests queue.
160
+ Scans request.json files under EVAL_REQUESTS_PATH/PROJ_DIR for status == 'FAILED'.
161
+ """
162
+ gid = _normalize_group_id(group_id)
163
+ base_dir = os.path.join(EVAL_REQUESTS_PATH, PROJ_DIR)
164
+ if not os.path.isdir(base_dir):
165
+ return pd.DataFrame(columns=["Alias", "Timestamp", "Error"])
166
+
167
+ rows = []
168
+ for root, _, files in os.walk(base_dir):
169
+ for fname in files:
170
+ if fname != "request.json":
171
+ continue
172
+ try:
173
+ with open(os.path.join(root, fname), "r") as f:
174
+ data = json.load(f)
175
+ req_gid = _normalize_group_id(data.get("group_id", ""))
176
+ if req_gid != gid:
177
+ continue
178
+ status = str(data.get("status", "")).upper()
179
+ if status != "FAILED":
180
+ continue
181
+ rows.append({
182
+ "Alias": data.get("alias", ""),
183
+ "Timestamp": data.get("timestamp", ""),
184
+ "Error": data.get("error", "Unknown error"),
185
+ })
186
+ except Exception:
187
+ continue
188
+
189
+ if not rows:
190
+ return pd.DataFrame(columns=["Alias", "Timestamp", "Error"])
191
+
192
+ df = pd.DataFrame(rows)
193
+ # Sort by timestamp descending (newest first)
194
+ if "Timestamp" in df.columns:
195
+ df = df.sort_values(by="Timestamp", ascending=False)
196
+ return df