Download app.py from atharva-manav/physicsbench-visualizer: direct link, hf CLI and curl.
- Browser
- Download file 3.94 kB
-
https://huggingface.co/spaces/atharva-manav/physicsbench-visualizer/resolve/main/app.py
- Command line
-
hf download hf://spaces/atharva-manav/physicsbench-visualizer/app.py
-
curl -L -o app.py https://huggingface.co/spaces/atharva-manav/physicsbench-visualizer/resolve/main/app.py
3.94 kB
| import json | |
| import gradio as gr | |
| from huggingface_hub import hf_hub_download | |
| DATASET_REPO = "atharva-manav/physicsbench-sampled" | |
| TASKS = [ | |
| "pb-hard-balance-hard-v1", | |
| "pb-hard-balance-medium-v1", | |
| "pb-hetbi-bowl-table-v1", | |
| "pb-hetbi-cracker-box-jaw-v1", | |
| "pb-hetbi-cracker-box-suction-v1", | |
| "pb-hetbi-cup-inversion-v1", | |
| "pb-hetbi-plate-shelf-v1", | |
| "pb-hobi-keyboard-typing-v1", | |
| "pb-hobi-plate-shelf-v1", | |
| "pb-pr-cup-extract-v1", | |
| "pb-pr-domino-select-v1", | |
| "pb-pr-domino-single-v1", | |
| "pb-pr-edge-slide-v1", | |
| "pb-pr-galileo-ramp-drop-v1", | |
| "pb-pr-mass-sort-v1", | |
| "pb-pr-mirror-pick-place-v1", | |
| "pb-pr-occluder-push-v1", | |
| "pb-pr-packing-v1", | |
| "pb-pr-recover-peg-insert-v1", | |
| "pb-pr-seesaw-balance-v1", | |
| "pb-pr-sheltered-grasp-v1", | |
| "pb-pr-slide-catch-v1", | |
| "pb-pr-slip-recovery-v1", | |
| "pb-pr-tool-retrieve-v1", | |
| "pb-puzzle-ball-cage-escape-v1", | |
| "pb-puzzle-gap-funnel-v1", | |
| "pb-puzzle-indirect-push-v1", | |
| "pb-puzzle-pick-place-ycb-v1", | |
| "pb-puzzle-ramp-sort-v1", | |
| "pb-puzzle-shape-stack-v1", | |
| "pb-puzzle-stack-collapse-recovery-v1", | |
| ] | |
| _info_cache = {} | |
| def get_info(task): | |
| if task not in _info_cache: | |
| try: | |
| path = hf_hub_download( | |
| repo_id=DATASET_REPO, | |
| filename=f"{task}/meta/info.json", | |
| repo_type="dataset", | |
| ) | |
| with open(path) as f: | |
| _info_cache[task] = json.load(f) | |
| except Exception as e: | |
| return None | |
| return _info_cache[task] | |
| def get_cameras(task): | |
| info = get_info(task) | |
| if not info: | |
| return [] | |
| return [k for k, v in info["features"].items() if v.get("dtype") == "video"] | |
| def on_task_change(task): | |
| cameras = get_cameras(task) | |
| info = get_info(task) | |
| n_ep = info.get("total_episodes", 5) if info else 5 | |
| task_desc = info.get("task_id", task) if info else task | |
| return ( | |
| gr.Dropdown(choices=cameras, value=cameras[0] if cameras else None, interactive=True), | |
| gr.Slider(minimum=0, maximum=n_ep - 1, step=1, value=0), | |
| task_desc, | |
| ) | |
| def load_video(task, episode_idx, camera): | |
| if not task or camera is None: | |
| return None, "Pick a task and camera then click Load." | |
| try: | |
| episode_idx = int(episode_idx) | |
| path = hf_hub_download( | |
| repo_id=DATASET_REPO, | |
| filename=f"{task}/videos/{camera}/chunk-000/file-{episode_idx:03d}.mp4", | |
| repo_type="dataset", | |
| ) | |
| return path, "" | |
| except Exception as e: | |
| return None, f"Error loading video: {e}" | |
| with gr.Blocks(title="PhysicsBench Visualizer", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("# PhysicsBench Sampled Dataset Visualizer") | |
| gr.Markdown( | |
| "31 physics-manipulation tasks · 5 episodes each · multiple cameras \n" | |
| f"Data: [{DATASET_REPO}](https://huggingface.co/datasets/{DATASET_REPO})" | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| task_dd = gr.Dropdown(choices=TASKS, value=TASKS[0], label="Task", interactive=True) | |
| camera_dd = gr.Dropdown(choices=[], label="Camera", interactive=True) | |
| episode_slider = gr.Slider(minimum=0, maximum=4, step=1, value=0, label="Episode", interactive=True) | |
| task_desc = gr.Textbox(label="Task ID", interactive=False) | |
| load_btn = gr.Button("Load Video", variant="primary") | |
| err_box = gr.Textbox(label="", visible=True, interactive=False, show_label=False) | |
| with gr.Column(scale=2): | |
| video_out = gr.Video(label="Episode Video", autoplay=True) | |
| task_dd.change(on_task_change, inputs=[task_dd], outputs=[camera_dd, episode_slider, task_desc]) | |
| load_btn.click(load_video, inputs=[task_dd, episode_slider, camera_dd], outputs=[video_out, err_box]) | |
| demo.load(on_task_change, inputs=[task_dd], outputs=[camera_dd, episode_slider, task_desc]) | |
| demo.launch() | |