diff --git a/artifact1/src/artifact1/cli.py b/artifact1/src/artifact1/cli.py new file mode 100644 index 0000000..303201a --- /dev/null +++ b/artifact1/src/artifact1/cli.py @@ -0,0 +1,100 @@ +import argparse +import json +import logging +from pathlib import Path +from typing import Any, Dict + +from artifact1.core import analyze_metrics + + +def _setup_logger() -> None: + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(levelname)s] %(message)s", + ) + + +def _validate_input_data(data: Any) -> Dict[str, Any]: + if not isinstance(data, dict): + raise ValueError("Input JSON must contain an object at root level.") + + required_fields = [ + "max_only_alerts", + "outlier_frequency", + "expires_at_dist_hours", + "retry_total_overhead", + ] + + for field in required_fields: + if field not in data: + raise ValueError(f"Missing required field '{field}' in input data.") + + if not isinstance(data["max_only_alerts"], int): + raise TypeError("'max_only_alerts' must be an integer.") + + for float_field in [ + "outlier_frequency", + "expires_at_dist_hours", + "retry_total_overhead", + ]: + if not isinstance(data[float_field], (int, float)): + raise TypeError(f"'{float_field}' must be a number (float or int).") + + return data + + +def main() -> None: + _setup_logger() + + parser = argparse.ArgumentParser( + description="Resonanzband Performance Analyse CLI" + ) + parser.add_argument( + "--input", + required=True, + help="Pfad zur JSON-Eingabedatei mit Performance-Daten.", + type=str, + ) + parser.add_argument( + "--output", + required=True, + help="Pfad zur JSON-Ausgabedatei mit Analyseergebnissen.", + type=str, + ) + + args = parser.parse_args() + + input_path = Path(args.input) + output_path = Path(args.output) + + if not input_path.exists(): + logging.error(f"Input file not found: {input_path}") + raise FileNotFoundError(f"Input file not found: {input_path}") + + logging.info(f"Loading performance data from {input_path}...") + + with input_path.open("r", encoding="utf-8") as f: + try: + data = json.load(f) + except json.JSONDecodeError as e: + logging.error(f"Invalid JSON structure: {e}") + raise + + validated_data = _validate_input_data(data) + + logging.info("Running performance analysis...") + results = analyze_metrics(validated_data) + + assert isinstance(results, dict), "analyze_metrics must return a dict" + + logging.info(f"Writing analysis results to {output_path}...") + output_path.parent.mkdir(parents=True, exist_ok=True) + + with output_path.open("w", encoding="utf-8") as f: + json.dump(results, f, indent=2, ensure_ascii=False) + + logging.info("Analysis complete. Results saved successfully.") + + +if __name__ == "__main__": + main()