Download reporting.py from finerobotics/annotation-studio: direct link, hf CLI and curl.
- Browser
- Download file 3.66 kB
-
https://huggingface.co/spaces/finerobotics/annotation-studio/resolve/main/reporting.py
- Command line
-
hf download hf://spaces/finerobotics/annotation-studio/reporting.py
-
curl -L -o reporting.py https://huggingface.co/spaces/finerobotics/annotation-studio/resolve/main/reporting.py
3.66 kB
| """Usage-derived cost reporting and links to materialized annotations.""" | |
| import json | |
| import math | |
| from datetime import UTC, datetime | |
| from studio import COPY | |
| def usage_costs(job, report): | |
| usage = report.get("usage") or {} | |
| manifest = report.get("manifest") or {} | |
| if not manifest: | |
| try: | |
| manifest = json.loads((getattr(job, "environment", None) or {}).get("ANNOTATION_MANIFEST", "{}")) | |
| except (TypeError, ValueError): | |
| manifest = {} | |
| rate = manifest.get("costs", {}).get("cpu_rate") | |
| seconds = getattr(getattr(job, "durations", None), "running_secs", None) | |
| if seconds is None and getattr(job, "started_at", None): | |
| end = getattr(job, "finished_at", None) or datetime.now(UTC) | |
| seconds = max(0, (end - job.started_at).total_seconds()) | |
| cpu = None | |
| if isinstance(seconds, (int, float)) and math.isfinite(seconds) and rate is not None: | |
| cpu = math.ceil(max(0, seconds) / 60) * rate | |
| inference = usage.get("measured_inference_usd") | |
| return { | |
| "inference_usd": inference, | |
| "cpu_usd": cpu, | |
| "total_usd": inference + cpu if inference is not None and cpu is not None else None, | |
| "uncertain_inference_usd": max( | |
| 0, usage.get("reserved_including_uncertain_usd", 0) - (inference or 0) | |
| ), | |
| "running_seconds": seconds, | |
| "basis": "Reported tokens × published rates, plus HF job runtime rounded to minutes. Final HF billing may differ.", | |
| "billing_url": "https://huggingface.co/settings/billing", | |
| } | |
| def _visualizer_episode(report): | |
| manifest = report.get("manifest", {}) | |
| written = report.get("written_episode_ids", []) | |
| # Old completed copy reports predate the explicit materialization checkpoint. | |
| if ( | |
| not written | |
| and report.get("status") == "completed" | |
| and not (report.get("copy_scope") or manifest.get("copy_scope")) | |
| ): | |
| written = [e["episode_index"] for e in report.get("episodes", []) if e["status"] == "completed"] | |
| if manifest.get("mode") != COPY or not written: | |
| return None | |
| return f"{manifest['output']}/{min(written)}" | |
| def annotation_url(report): | |
| """Link to the first playable exported episode's language annotations.""" | |
| episode = _visualizer_episode(report) | |
| return f"https://lerobot-visualize-dataset.hf.space/{episode}?tab=annotations" if episode else None | |
| def hand_visualizer_url(report): | |
| """Link native hand exports to the configured synchronized 3D viewer.""" | |
| if not report.get("manifest", {}).get("hand_actions"): | |
| return None | |
| episode = _visualizer_episode(report) | |
| base = "https://lerobot-visualize-dataset.hf.space" | |
| return f"{base}/{episode}?tab=hands" if episode else None | |
| def episode_progress(report): | |
| """Count successful labeling separately from playable dataset exports.""" | |
| episodes = report.get("episodes", []) | |
| expected = report["expected_episodes"] | |
| completed = sum(e["status"] == "completed" for e in episodes) | |
| written = report.get("written_episode_ids") | |
| # Compatibility with reports before per-episode export checkpoints. | |
| exported = ( | |
| len(set(written)) | |
| if written is not None | |
| else (completed if report.get("status") == "completed" else 0) | |
| ) | |
| return { | |
| "expected": expected, | |
| "completed": completed, | |
| "exported": exported, | |
| "export_pending": max(0, completed - exported), | |
| "failed": sum(e["status"] == "failed" for e in episodes), | |
| "stopped": sum(e["status"] in {"time_stopped", "budget_stopped"} for e in episodes), | |
| "pending": max(0, expected - len(episodes)), | |
| } | |