Paul Gavrikov
initial app
0e48243
raw
history blame
3.38 kB
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()