"""Scenario loader — load scenario definitions from JSON files.""" from __future__ import annotations import json import os import shutil from pathlib import Path from typing import Optional WORKBOOKS_DIR = os.getenv("WORKBOOKS_DIR", str(Path(__file__).resolve().parent.parent / "workbooks")) SCENARIOS_DIR = os.getenv("SCENARIOS_DIR", str(Path(__file__).resolve().parent.parent / "scenarios")) FIXTURES_DIR = os.path.join(WORKBOOKS_DIR, "fixtures") TEMPLATES_DIR = os.path.join(WORKBOOKS_DIR, "templates") def list_scenarios() -> list[dict]: """List all available scenario definitions.""" if not os.path.isdir(SCENARIOS_DIR): return [] scenarios = [] for f in sorted(os.listdir(SCENARIOS_DIR)): if not f.endswith(".json"): continue try: data = load_scenario_def(f.replace(".json", "")) scenarios.append({ "scenario_id": data.get("id", f.replace(".json", "")), "description": data.get("description", ""), "workbook": data.get("workbook", ""), "max_steps": data.get("max_steps", 50), }) except Exception: continue return scenarios def load_scenario_def(scenario_id: str) -> dict: """Load a single scenario definition JSON.""" path = os.path.join(SCENARIOS_DIR, f"{scenario_id}.json") if not os.path.isfile(path): raise FileNotFoundError(f"Scenario '{scenario_id}' not found at {path}") with open(path) as f: return json.load(f) def prepare_workbook_for_session(scenario_id: str, session_id: str) -> str: """Copy the template workbook to a session-specific fixture path. Returns the path to the session's workbook copy. """ scenario = load_scenario_def(scenario_id) template_name = scenario.get("workbook", f"{scenario_id}.xlsx") template_path = os.path.join(TEMPLATES_DIR, template_name) if not os.path.isfile(template_path): raise FileNotFoundError(f"Template workbook not found: {template_path}") os.makedirs(FIXTURES_DIR, exist_ok=True) session_wb_path = os.path.join(FIXTURES_DIR, f"{session_id}_{template_name}") shutil.copy2(template_path, session_wb_path) return session_wb_path