From 5fdb1e6eafa00566ad36d336511c140a73715350 Mon Sep 17 00:00:00 2001 From: Kai Chappell Date: Thu, 29 Jan 2026 17:56:15 +0000 Subject: [PATCH] Add report data models --- src/py_dvt_ate/reporting/models.py | 70 ++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/py_dvt_ate/reporting/models.py diff --git a/src/py_dvt_ate/reporting/models.py b/src/py_dvt_ate/reporting/models.py new file mode 100644 index 0000000..3175026 --- /dev/null +++ b/src/py_dvt_ate/reporting/models.py @@ -0,0 +1,70 @@ +"""Data models for report generation. + +This module defines dataclasses for report configuration and data structures +used throughout the reporting pipeline. +""" + +from dataclasses import dataclass, field +from pathlib import Path + +import pandas as pd + +from py_dvt_ate.data.models import TestResult, TestRun + + +@dataclass +class ReportConfig: + """Configuration for report generation. + + Attributes: + company_name: Company name to display in report header. + logo_path: Path to company logo image file (optional). + include_charts: Whether to include charts in the report. + chart_dpi: DPI for chart images (higher = better quality but larger file). + """ + + company_name: str = "py_dvt_ate" + logo_path: Path | None = None + include_charts: bool = True + chart_dpi: int = 150 + + +@dataclass +class ReportData: + """Data container for report generation. + + Contains all data needed to generate a test report including + test run metadata, results, measurements, and generated charts. + + Attributes: + run: Test run metadata. + results: List of test results with pass/fail status. + measurements: DataFrame of time-series measurements (optional). + charts: Dictionary mapping chart names to base64-encoded PNG images. + config: Report configuration settings. + """ + + run: TestRun + results: list[TestResult] + measurements: pd.DataFrame | None = None + charts: dict[str, str] = field(default_factory=dict) + config: ReportConfig = field(default_factory=ReportConfig) + + @property + def passed_count(self) -> int: + """Count of results that passed.""" + return sum(1 for r in self.results if r.passed is True) + + @property + def failed_count(self) -> int: + """Count of results that failed.""" + return sum(1 for r in self.results if r.passed is False) + + @property + def overall_status(self) -> str: + """Overall test status: PASS, FAIL, or ERROR.""" + if self.run.status.value == "error": + return "ERROR" + if self.failed_count > 0: + return "FAIL" + return "PASS"