Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import json | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| from typing import Any | |
| from uuid import uuid4 | |
| import numpy as np | |
| class SimulationEncoder(json.JSONEncoder): | |
| def default(self, obj): | |
| if isinstance(obj, (np.integer, np.int64, np.int32, np.int16, np.int8)): | |
| return int(obj) | |
| if isinstance(obj, (np.floating, np.float64, np.float32, np.float16)): | |
| return float(obj) | |
| if isinstance(obj, (np.bool_, bool)): | |
| return bool(obj) | |
| if isinstance(obj, (np.ndarray, np.generic)): | |
| if hasattr(obj, "tolist"): | |
| return obj.tolist() | |
| return str(obj) | |
| if isinstance(obj, (datetime, Path)): | |
| return str(obj) | |
| try: | |
| return super().default(obj) | |
| except TypeError: | |
| return str(obj) | |
| DEFAULT_HISTORY_PATH = Path("data/run_history.json") | |
| def _ensure_parent(path: Path) -> None: | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| def _safe_load_json_array(path: Path) -> list[dict[str, Any]]: | |
| if not path.exists(): | |
| return [] | |
| try: | |
| data = json.loads(path.read_text(encoding="utf-8")) | |
| except json.JSONDecodeError: | |
| return [] | |
| if not isinstance(data, list): | |
| return [] | |
| return [x for x in data if isinstance(x, dict)] | |
| def build_run_record(sim_output: dict[str, Any]) -> dict[str, Any]: | |
| series = sim_output.get("series", []) | |
| config = sim_output.get("config", {}) | |
| final = series[-1] if series else {} | |
| return { | |
| "run_id": str(uuid4()), | |
| "created_at_utc": datetime.now(timezone.utc).isoformat(), | |
| "config": config, | |
| "final": final, | |
| "ticks_recorded": len(series), | |
| "series": series, | |
| } | |
| def append_run_history(sim_output: dict[str, Any], path: Path = DEFAULT_HISTORY_PATH) -> dict[str, Any]: | |
| _ensure_parent(path) | |
| runs = _safe_load_json_array(path) | |
| record = build_run_record(sim_output) | |
| runs.append(record) | |
| path.write_text(json.dumps(runs, indent=2, cls=SimulationEncoder), encoding="utf-8") | |
| return record | |
| def load_run_history(path: Path = DEFAULT_HISTORY_PATH) -> list[dict[str, Any]]: | |
| return _safe_load_json_array(path) | |