Add heatmap_visualization/src/heatmap_visualization/cli.py
This commit is contained in:
parent
ff2a729aa8
commit
c10d6ceb1b
1 changed files with 70 additions and 0 deletions
70
heatmap_visualization/src/heatmap_visualization/cli.py
Normal file
70
heatmap_visualization/src/heatmap_visualization/cli.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import argparse
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import pandas as pd
|
||||
from heatmap_visualization import core
|
||||
|
||||
# Configure logging for CI and debugging
|
||||
logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _validate_input_data(data: Any) -> pd.DataFrame:
|
||||
"""Validate that the input data conforms to the expected LogData structure."""
|
||||
if isinstance(data, list):
|
||||
try:
|
||||
df = pd.DataFrame(data)
|
||||
except Exception as e:
|
||||
raise ValueError(f"Could not convert input list to DataFrame: {e}")
|
||||
elif isinstance(data, pd.DataFrame):
|
||||
df = data.copy()
|
||||
else:
|
||||
raise TypeError("Input data must be a list of dicts or a pandas.DataFrame.")
|
||||
|
||||
required_fields = {"worker_start_offset", "expires_at_dist_hours", "retry_total_overhead_ms"}
|
||||
missing = required_fields - set(df.columns)
|
||||
if missing:
|
||||
raise ValueError(f"Input data missing required fields: {', '.join(missing)}")
|
||||
|
||||
# Validate types
|
||||
for field in required_fields:
|
||||
if not pd.api.types.is_numeric_dtype(df[field]):
|
||||
raise ValueError(f"Field '{field}' must be numeric.")
|
||||
return df
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Command-line entry point for generating the Run 26 heatmap visualization."""
|
||||
parser = argparse.ArgumentParser(description="Generate a latency heatmap from run log data.")
|
||||
parser.add_argument("--input", required=True, help="Path to input log JSON file.")
|
||||
parser.add_argument("--output", required=True, help="Path to output PNG file.")
|
||||
args = parser.parse_args()
|
||||
|
||||
input_path = Path(args.input)
|
||||
output_path = Path(args.output)
|
||||
|
||||
if not input_path.exists():
|
||||
logger.error(f"Input file not found: {input_path}")
|
||||
raise FileNotFoundError(f"Input file not found: {input_path}")
|
||||
|
||||
logger.info(f"Loading JSON data from {input_path}")
|
||||
with input_path.open("r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
df = _validate_input_data(data)
|
||||
|
||||
logger.info("Generating heatmap figure...")
|
||||
fig = core.generate_heatmap(df)
|
||||
|
||||
logger.info(f"Saving heatmap to {output_path}")
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
fig.savefig(output_path, dpi=300, bbox_inches="tight")
|
||||
|
||||
logger.info("Heatmap generation completed successfully.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in a new issue