"""CADGenBench Leaderboard Space - Gradio UI assembly. Read path lives in :mod:`leaderboard`. Submit-tab validation lives in :mod:`submit`. Both are wired into the Gradio app below. """ from __future__ import annotations import logging import gradio as gr from gradio_leaderboard import Leaderboard from leaderboard import ( HF_DATA_REPO, HF_SUBMISSIONS_REPO, load_leaderboard, ) from submit import handle_submit # Surface module-level logger.info / logger.warning / logger.exception # calls from leaderboard.py + submit.py in the Space's runtime logs. # Otherwise they go nowhere and any refresh / worker pathology is # silent. Format keeps timestamps + module + level + message. logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s [%(name)s] %(message)s", ) ABOUT_MD = f"""## About **CADGenBench** evaluates AI-driven CAD generation: how well a model can turn a description of a mechanical part into a valid, geometrically correct 3D model. - **Reference baseline**: an iterative AI agent that writes build123d Python. - **Submission flow**: upload a zip of per-fixture STEP files; the Space runs the eval and appends a row to the submissions dataset. - **Datasets**: fixture inputs in [`{HF_DATA_REPO}`](https://huggingface.co/datasets/{HF_DATA_REPO}); submissions and computed results in [`{HF_SUBMISSIONS_REPO}`](https://huggingface.co/datasets/{HF_SUBMISSIONS_REPO}). - **Code**: [`huggingface/cadgenbench`](https://github.com/huggingface/cadgenbench). """ with gr.Blocks(title="CADGenBench Leaderboard", theme=gr.themes.Soft()) as app: gr.Markdown( "# CADGenBench Leaderboard\n" "_Benchmarking AI-driven CAD generation._" ) with gr.Tab("Leaderboard"): df_view = Leaderboard( value=load_leaderboard(), search_columns=["submission_name", "submitter_name"], label="Results (sorted by aggregate CAD score)", ) refresh_btn = gr.Button("Refresh", size="sm") refresh_btn.click(fn=load_leaderboard, outputs=df_view) with gr.Tab("Submit"): gr.Markdown( f""" **Submission format.** A single zip with: - one folder per fixture in `{HF_DATA_REPO}`, each containing `output.step`; - a top-level `meta.json`: ```json {{ "submitter_name": "your name or team", "submission_name": "MyAgent v2.3 (or whatever describes your system)", "agent_url": "https://github.com/... (optional)", "notes": "free text, optional, max 500 chars, single line, plain text", "agree_to_publish": true }} ``` **Submission name.** Free text describing the system being benchmarked, however you choose to describe it. The benchmark is system-agnostic - your submission may use no LLM, one, or many. If you want to disclose your stack, put it here or in `notes`. **Notes field.** Plain text only (no markdown / HTML). Capped at 500 chars and stripped to a single line. Shown in the per-submission detail view, not in the main leaderboard table. **Consent.** `"agree_to_publish": true` in `meta.json` is your consent to publish the resulting row on the public leaderboard. """ ) zip_in = gr.File(label="Submission ZIP", file_types=[".zip"]) submit_btn = gr.Button("Submit", variant="primary") submit_out = gr.Markdown() submit_btn.click( fn=handle_submit, inputs=[zip_in], outputs=submit_out, ) with gr.Tab("About"): gr.Markdown(ABOUT_MD) # gradio_leaderboard.Leaderboard handles its own update path # cleanly; bind a Timer to push a fresh dataframe every 10 seconds. auto_refresh_timer = gr.Timer(10) auto_refresh_timer.tick(fn=load_leaderboard, outputs=df_view) if __name__ == "__main__": app.launch()