diff --git a/retry_tail_analysis/src/retry_tail_analysis/cli.py b/retry_tail_analysis/src/retry_tail_analysis/cli.py new file mode 100644 index 0000000..5bd18e8 --- /dev/null +++ b/retry_tail_analysis/src/retry_tail_analysis/cli.py @@ -0,0 +1,60 @@ +import argparse +import json +import sys +from pathlib import Path +from typing import List + +from retry_tail_analysis.core import analyze_retry_tail, ExperimentData + + +def _load_experiment_data(file_path: Path) -> List[ExperimentData]: + """Lädt und validiert Experimentdaten aus einer JSON-Datei.""" + if not file_path.exists() or not file_path.is_file(): + raise FileNotFoundError(f"Eingabedatei nicht gefunden: {file_path}") + + with file_path.open(encoding="utf-8") as f: + try: + raw_data = json.load(f) + except json.JSONDecodeError as e: + raise ValueError(f"Fehler beim Lesen der JSON-Datei: {e}") from e + + if not isinstance(raw_data, list): + raise ValueError("Erwartet eine Liste von Experimentobjekten im JSON.") + + data_objects = [] + for idx, entry in enumerate(raw_data, start=1): + if not isinstance(entry, dict): + raise TypeError(f"Eintrag {idx} ist kein Objekt: {entry}") + required_fields = {"run_id", "retry_tailp99", "threshold"} + if not required_fields.issubset(entry.keys()): + missing = required_fields - set(entry.keys()) + raise ValueError(f"Fehlende Felder in Eintrag {idx}: {missing}") + try: + run_id = str(entry["run_id"]) + retry_tailp99 = float(entry["retry_tailp99"]) + threshold = float(entry["threshold"]) + except (ValueError, TypeError) as e: + raise ValueError(f"Ungültige Typen in Eintrag {idx}: {e}") from e + data_objects.append(ExperimentData(run_id, retry_tailp99, threshold)) + assert data_objects, "Keine gültigen Experimentdaten gefunden." + return data_objects + + +def main() -> None: + """CLI-Einstiegspunkt: führt die Analyse basierend auf JSON-Input aus.""" + parser = argparse.ArgumentParser(description="Analyse der retry_tailp99-Werte aus JSON-Experimentdaten.") + parser.add_argument("--input", required=True, help="Pfad zur JSON-Datei mit Experimentdaten.") + args = parser.parse_args() + + input_path = Path(args.input) + try: + data = _load_experiment_data(input_path) + result = analyze_retry_tail(data) + print(f"Aggregierter retry_tailp99-Wert: {result:.4f}") + except Exception as exc: # noqa: BLE001 + print(f"Fehler: {exc}", file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + main()