from __future__ import annotations import csv import json from pathlib import Path from typing import Any, Iterable def ensure_dir(path: Path) -> Path: path.mkdir(parents=True, exist_ok=True) return path def write_json(path: Path, data: Any) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8") def write_text(path: Path, data: str) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(data, encoding="utf-8") def write_csv(path: Path, rows: Iterable[dict[str, Any]]) -> None: rows = list(rows) path.parent.mkdir(parents=True, exist_ok=True) if not rows: path.write_text("", encoding="utf-8") return fieldnames: list[str] = [] for row in rows: for key in row.keys(): if key not in fieldnames: fieldnames.append(key) with path.open("w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=fieldnames) writer.writeheader() writer.writerows(rows)