"""Frontend Space entry: form + leaderboard view + queue. v0.6: state lives on shared `/data` POSIX volume; this process is read-only against the queue / results, and only ever writes via the atomic enqueue in ``src.submission.frontend``. """ from __future__ import annotations import logging import gradio as gr import pandas as pd from src.about import ( ABOUT_TEXT, CITATION_BUTTON_LABEL, CITATION_BUTTON_TEXT, DATASET_LAYOUT_TEXT, INTRODUCTION_TEXT, SUBMIT_INSTRUCTIONS, TITLE, ) from src.display.css_html_js import custom_css from src.envs import ensure_data_layout from src.populate import get_history_df, get_leaderboard_df, get_queue_df from src.submission.frontend import submit_task from src.tasks import TASKS logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s") logger = logging.getLogger(__name__) ensure_data_layout() def _safe_lb(task_name: str) -> pd.DataFrame: try: return get_leaderboard_df(task_name) except Exception as e: logger.warning("leaderboard load failed for %s: %s", task_name, e) return pd.DataFrame() def _safe_history(task_name: str) -> pd.DataFrame: try: return get_history_df(task_name) except Exception as e: logger.warning("history load failed for %s: %s", task_name, e) return pd.DataFrame() def _safe_queue() -> pd.DataFrame: try: return get_queue_df() except Exception as e: logger.warning("queue load failed: %s", e) return pd.DataFrame() def _on_submit(display_name, task_name, user_dataset): res = submit_task(display_name=display_name, task_name=task_name, user_dataset=user_dataset) return res["message"], _safe_queue() task_keys = list(TASKS.keys()) task_choices = [(TASKS[k].display_name, k) for k in task_keys] demo = gr.Blocks(css=custom_css, title="PhysInOne Benchmark") with demo: gr.HTML(TITLE) gr.Markdown(INTRODUCTION_TEXT, elem_classes="markdown-text") with gr.Tabs(elem_classes="tab-buttons"): # -------------------- Leaderboard -------------------- with gr.TabItem("πŸ… Leaderboard", id=0): gr.Markdown( "Leaderboard data is refreshed infrequently. Please use the \"πŸ”„ Refresh\" button under each task to pull the latest results.", elem_classes="markdown-text", ) for tk in task_keys: spec = TASKS[tk] with gr.Accordion(f"🎯 {spec.display_name}", open=True): gr.Markdown(spec.description, elem_classes="markdown-text") gr.Markdown("**Expected scene layout:**\n" + spec.expected_scene_layout) lb = gr.Dataframe(value=_safe_lb(tk), interactive=False, wrap=True) gr.Button("πŸ”„ Refresh", size="sm").click( fn=lambda k=tk: _safe_lb(k), outputs=lb ) with gr.Accordion("πŸ“œ All submissions (history)", open=False): hist = gr.Dataframe(value=_safe_history(tk), interactive=False, wrap=True) gr.Button("πŸ”„ Refresh History", size="sm").click( fn=lambda k=tk: _safe_history(k), outputs=hist ) # -------------------- Submit -------------------- with gr.TabItem("πŸš€ Submit", id=1): gr.Markdown(SUBMIT_INSTRUCTIONS, elem_classes="markdown-text") gr.Markdown(DATASET_LAYOUT_TEXT, elem_classes="markdown-text") with gr.Row(): display_input = gr.Textbox(label="Display Name", placeholder="Awesome Team") task_input = gr.Dropdown( label="Task", choices=task_choices, value=task_keys[0] if task_keys else None, ) ds_input = gr.Textbox(label="User dataset (username/repo)", placeholder="userA/my-results") submit_btn = gr.Button("Submit", variant="primary") submit_msg = gr.Markdown() # -------------------- Queue -------------------- with gr.TabItem("πŸ“‹ Queue", id=2): gr.Markdown( "Recent submissions and their statuses. Status flow: `pending β†’ running β†’ done / failed`." " The queue **auto-refreshes every 15 seconds**; leaderboard tables require manual refresh.", elem_classes="markdown-text", ) queue_table = gr.Dataframe(value=_safe_queue(), interactive=False, wrap=True) with gr.Row(): gr.Button("πŸ”„ Refresh Now").click(fn=_safe_queue, outputs=queue_table) try: gr.Timer(value=15.0).tick(fn=_safe_queue, outputs=queue_table) except AttributeError: logger.warning("gr.Timer unavailable; falling back to manual refresh.") # -------------------- About -------------------- with gr.TabItem("πŸ“ About", id=3): gr.Markdown(ABOUT_TEXT, elem_classes="markdown-text") submit_btn.click( fn=_on_submit, inputs=[display_input, task_input, ds_input], outputs=[submit_msg, queue_table], ) with gr.Row(): with gr.Accordion("πŸ“™ Citation", open=False): gr.Textbox( value=CITATION_BUTTON_TEXT, label=CITATION_BUTTON_LABEL, lines=10, elem_id="citation-button", show_copy_button=True, ) if __name__ == "__main__": demo.queue(default_concurrency_limit=8).launch()