Add export-report CLI command
This commit is contained in:
@@ -208,6 +208,127 @@ def list_runs_cmd(
|
||||
repo.close()
|
||||
|
||||
|
||||
@app.command(name="export-report")
|
||||
def export_report_cmd(
|
||||
run_id: Annotated[
|
||||
str,
|
||||
typer.Argument(help="Test run ID (short 8-char or full UUID)."),
|
||||
],
|
||||
output: Annotated[
|
||||
str | None,
|
||||
typer.Option("--output", "-o", help="Output PDF file path."),
|
||||
] = None,
|
||||
company: Annotated[
|
||||
str | None,
|
||||
typer.Option("--company", help="Company name for report header."),
|
||||
] = None,
|
||||
config_file: Annotated[
|
||||
str | None,
|
||||
typer.Option("--config", "-c", help="Path to configuration YAML file."),
|
||||
] = None,
|
||||
) -> None:
|
||||
"""Export a PDF report for a test run.
|
||||
|
||||
Generate a professional PDF report from test results. The run_id can be
|
||||
the short 8-character ID shown by list-runs, or the full UUID.
|
||||
|
||||
Examples:
|
||||
py-dvt-ate export-report abc12345
|
||||
py-dvt-ate export-report abc12345 --output ./my_report.pdf
|
||||
py-dvt-ate export-report abc12345 --company "My Company"
|
||||
"""
|
||||
from pathlib import Path
|
||||
from uuid import UUID
|
||||
|
||||
from rich.console import Console
|
||||
|
||||
from py_dvt_ate.app.config import load_config
|
||||
from py_dvt_ate.data.repository import SQLiteRepository
|
||||
|
||||
console = Console()
|
||||
|
||||
# Check for reporting dependencies
|
||||
try:
|
||||
from py_dvt_ate.reporting import ReportConfig, ReportGenerator
|
||||
except ImportError:
|
||||
console.print(
|
||||
"[red]Error:[/red] Report generation requires additional dependencies.\n"
|
||||
"Install with: [cyan]pip install py_dvt_ate[reports][/cyan]"
|
||||
)
|
||||
raise typer.Exit(1)
|
||||
|
||||
# Load config
|
||||
if config_file is None:
|
||||
config_path = Path("config/default.yaml")
|
||||
if config_path.exists():
|
||||
config_file = str(config_path)
|
||||
|
||||
config = load_config(config_file)
|
||||
|
||||
# Create repository
|
||||
repo = SQLiteRepository(
|
||||
db_path=config.data.database_path,
|
||||
measurements_dir=config.data.measurements_dir,
|
||||
)
|
||||
|
||||
try:
|
||||
# Resolve short ID to full UUID
|
||||
full_run_id: UUID | None = None
|
||||
|
||||
if len(run_id) == 8:
|
||||
# Short ID - need to find full UUID
|
||||
all_runs = repo.get_all_runs()
|
||||
matching_runs = [r for r in all_runs if r.id.startswith(run_id)]
|
||||
|
||||
if not matching_runs:
|
||||
console.print(f"[red]Error:[/red] No test run found with ID starting with '{run_id}'")
|
||||
raise typer.Exit(1)
|
||||
elif len(matching_runs) > 1:
|
||||
console.print(f"[red]Error:[/red] Multiple runs match '{run_id}'. Use full UUID.")
|
||||
for run in matching_runs:
|
||||
console.print(f" - {run.id} ({run.test_name})")
|
||||
raise typer.Exit(1)
|
||||
|
||||
full_run_id = UUID(matching_runs[0].id)
|
||||
else:
|
||||
try:
|
||||
full_run_id = UUID(run_id)
|
||||
except ValueError:
|
||||
console.print(f"[red]Error:[/red] Invalid run ID: '{run_id}'")
|
||||
raise typer.Exit(1)
|
||||
|
||||
# Create report config
|
||||
report_config = ReportConfig(
|
||||
company_name=company or config.reporting.company_name,
|
||||
logo_path=Path(config.reporting.logo_path) if config.reporting.logo_path else None,
|
||||
include_charts=config.reporting.include_charts,
|
||||
chart_dpi=config.reporting.chart_dpi,
|
||||
)
|
||||
|
||||
# Create generator
|
||||
generator = ReportGenerator(
|
||||
repository=repo,
|
||||
config=report_config,
|
||||
reports_dir=Path(config.data.reports_dir),
|
||||
)
|
||||
|
||||
# Generate report
|
||||
console.print(f"[cyan]Generating report for run {str(full_run_id)[:8]}...[/cyan]")
|
||||
|
||||
output_path = Path(output) if output else None
|
||||
pdf_path = generator.generate(full_run_id, output_path)
|
||||
|
||||
console.print(f"[green]Report saved to:[/green] {pdf_path}")
|
||||
|
||||
except typer.Exit:
|
||||
raise
|
||||
except Exception as e:
|
||||
console.print(f"[red]Error generating report:[/red] {e}")
|
||||
raise typer.Exit(1)
|
||||
finally:
|
||||
repo.close()
|
||||
|
||||
|
||||
@app.command(name="query")
|
||||
def query_cmd(
|
||||
instrument: Annotated[
|
||||
|
||||
Reference in New Issue
Block a user