Generates HTML dashboard for experiment results.
| 18 | |
| 19 | |
| 20 | class ResultsHTMLGenerator: |
| 21 | """Generates HTML dashboard for experiment results.""" |
| 22 | |
| 23 | def __init__(self, experiment_dir: Path): |
| 24 | self.experiment_dir = Path(experiment_dir) |
| 25 | self.templates_dir = Path(__file__).parent.parent / "templates" |
| 26 | self.html_dir = self.experiment_dir / "html" |
| 27 | |
| 28 | def generate_all(self): |
| 29 | """Generate all HTML pages for the experiment.""" |
| 30 | # Create HTML directory |
| 31 | self.html_dir.mkdir(exist_ok=True) |
| 32 | |
| 33 | # Load experiment data |
| 34 | experiment_data = self._load_experiment_data() |
| 35 | if not experiment_data: |
| 36 | print(f"Error: Could not load experiment data from {self.experiment_dir}") |
| 37 | return False |
| 38 | |
| 39 | # Generate summary page |
| 40 | self._generate_summary_page(experiment_data) |
| 41 | |
| 42 | # Generate detail pages for each task |
| 43 | for task_data in experiment_data["tasks"]: |
| 44 | self._generate_task_detail_pages(task_data) |
| 45 | |
| 46 | return True |
| 47 | |
| 48 | def _load_experiment_data(self) -> Dict[str, Any]: |
| 49 | """Load experiment data from results.json and run_metadata.json.""" |
| 50 | results_path = self.experiment_dir / "results.json" |
| 51 | metadata_path = self.experiment_dir / "run_metadata.json" |
| 52 | |
| 53 | if not results_path.exists(): |
| 54 | print(f"Error: results.json not found in {self.experiment_dir}") |
| 55 | return None |
| 56 | |
| 57 | try: |
| 58 | with open(results_path, "r") as f: |
| 59 | results_data = json.load(f) |
| 60 | |
| 61 | metadata = {} |
| 62 | if metadata_path.exists(): |
| 63 | with open(metadata_path, "r") as f: |
| 64 | metadata = json.load(f) |
| 65 | |
| 66 | # Process results into a more usable format |
| 67 | tasks = [] |
| 68 | for result in results_data.get("results", []): |
| 69 | # Results are already in the correct format, just use them directly |
| 70 | tasks.append(result) |
| 71 | |
| 72 | # Note: Most summary stats are now computed in summarize_results() |
| 73 | # and passed via the 'summary' key. We only compute experiment-level |
| 74 | # metadata here that isn't available from the results. |
| 75 | |
| 76 | return { |
| 77 | "experiment_id": self.experiment_dir.name, |
no outgoing calls
no test coverage detected