# -*- coding: utf-8 -*- """RoboCasa Kitchen Leaderboard — FastAPI. Serves static index.html and accepts /submit, writing one JSON file per submission to a PRIVATE HF dataset (ginigen-ai/robocasa-submissions).""" import os, io, json, datetime, re from fastapi import FastAPI, Form from fastapi.responses import FileResponse, JSONResponse from huggingface_hub import HfApi HERE = os.path.dirname(os.path.abspath(__file__)) DS_REPO = "ginigen-ai/robocasa-submissions" TOKEN = os.environ.get("HF_TOKEN") app = FastAPI(title="RoboCasa Kitchen Leaderboard", docs_url=None, redoc_url=None) @app.get("/") def index(): return FileResponse(os.path.join(HERE, "index.html")) @app.get("/health") def health(): return JSONResponse({"status": "ok", "token_configured": bool(TOKEN)}) @app.post("/submit") async def submit(model: str = Form(...), sr: float = Form(...), protocol: str = Form(...), paper: str = Form(""), submitter: str = Form(...)): if not TOKEN: return JSONResponse({"ok": False, "error": "server token not configured"}, status_code=500) try: srv = float(sr) except Exception: return JSONResponse({"ok": False, "error": "SR must be a number"}, status_code=400) if not (0.0 <= srv <= 100.0): return JSONResponse({"ok": False, "error": "SR must be 0-100"}, status_code=400) rec = {"model": model.strip()[:120], "sr": round(srv, 2), "protocol": protocol.strip()[:60], "paper": paper.strip()[:300], "submitter": submitter.strip()[:120], "ts": datetime.datetime.utcnow().isoformat() + "Z", "status": "pending"} if not rec["model"] or not rec["submitter"]: return JSONResponse({"ok": False, "error": "model and submitter required"}, status_code=400) safe = re.sub(r"[^A-Za-z0-9_-]", "", model)[:30] or "model" fname = "submissions/%s_%s.json" % (rec["ts"].replace(":", "").replace(".", ""), safe) try: HfApi(token=TOKEN).upload_file( path_or_fileobj=io.BytesIO(json.dumps(rec, ensure_ascii=False, indent=2).encode("utf-8")), path_in_repo=fname, repo_id=DS_REPO, repo_type="dataset", commit_message="submit: %s by %s" % (rec["model"], rec["submitter"])) return JSONResponse({"ok": True}) except Exception as e: return JSONResponse({"ok": False, "error": str(e)[:200]}, status_code=500)