Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import json, os, time, uuid | |
| from eval_utils import evaluate_submission | |
| from threading import Lock | |
| # Setup | |
| GROUND_TRUTH = "ground_truth.json" | |
| SUB_DIR = "submissions" | |
| RATE_LIMIT = 60 | |
| os.makedirs(SUB_DIR, exist_ok=True) | |
| user_last = {} | |
| lock = Lock() | |
| def show_form(profile: gr.OAuthProfile | None): | |
| visible = profile is not None | |
| welcome = (f"## π Welcome, {profile.username}! Ready to submit?" | |
| if visible else "## π Please sign in to submit.") | |
| return welcome, gr.Textbox(visible=visible) , gr.File(visible=visible), \ | |
| gr.Checkbox(visible=visible), gr.Button(visible=visible) | |
| def submit(submission_id: str, submission_file: str, is_private: bool, profile: gr.OAuthProfile | None): | |
| if not profile: | |
| raise gr.Error("π Please sign in first.") | |
| username = profile.username | |
| with lock: | |
| now = time.time() | |
| if now - user_last.get(username, 0) < RATE_LIMIT: | |
| remaining = int(RATE_LIMIT - (now - user_last[username])) | |
| raise gr.Error(f"β±οΈ Wait {remaining}s before retrying.") | |
| user_last[username] = now | |
| with open(submission_file.name, "rb") as file: | |
| prediction_json = json.load(file) | |
| with open(GROUND_TRUTH, "rb") as file: | |
| ground_truth_json = json.load(file) | |
| score = evaluate_submission(prediction_json, ground_truth_json) | |
| if not is_private: | |
| sid = str(uuid.uuid4()) | |
| submission_record = f"{username}_{sid}_{submission_id}" | |
| json.dump({ | |
| "username": username, | |
| "identifier": submission_id, | |
| "timestamp": now, | |
| "submission": prediction_json | |
| }, open(os.path.join(SUB_DIR, submission_record + ".json"), "w")) | |
| return gr.Text(f"{score:.4f}", visible=True) | |
| def get_leaderboard(): | |
| records = [] | |
| # for fn in os.listdir(SUB_DIR): | |
| # r = json.load(open(os.path.join(SUB_DIR, fn))) | |
| # if not r.get("private", False): | |
| # records.append(r) | |
| records.sort(key=lambda x: -x["score"]) | |
| if not records: | |
| return "**No submissions yet**" | |
| lines = ["| User | Score | Time |", "|---|---|---|"] | |
| for r in records[:10]: | |
| t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(r["timestamp"])) | |
| lines.append(f"| {r['username']} | {r['score']:.4f} | {t} |") | |
| return "\n".join(lines) | |
| with gr.Blocks() as demo: | |
| gr.LoginButton() | |
| welcome_md = gr.Markdown("Please sign in to be able to submit.") | |
| submission_file = gr.File(label="Prediction (.json)", visible=False) | |
| submission_id = gr.Textbox(label="Submission identifier", visible=False) | |
| private_flag = gr.Checkbox(label="Do not save my submission", value=False, visible=False) | |
| submit_btn = gr.Button("Submit", visible=False) | |
| result = gr.Textbox(label="β Your score", visible=False) | |
| leaderboard_heading_md = gr.Markdown("## π Public Leaderboard") | |
| leaderboard_md = gr.Markdown(get_leaderboard()) | |
| # Load login state β show/hide components | |
| demo.load(fn=show_form, | |
| inputs=[], | |
| outputs=[welcome_md, submission_id, submission_file, private_flag, submit_btn]) | |
| # Submit button only shown post-login | |
| submit_btn.click(fn=submit, | |
| inputs=[submission_id, submission_file, private_flag], | |
| outputs=result) | |
| demo.launch() |