Skip to content

Reporting API

The reporting module generates HTML and PDF reports from detection results.

Module Reference

reporting

Report generation utilities.

Classes

ReportBuilder

ReportBuilder(detector: ShortcutDetector)

Generate comprehensive reports from shortcut detection results.

Supports HTML and PDF output formats with visualizations and CSV export.

Initialize report builder.

Parameters:

Name Type Description Default
detector ShortcutDetector

Fitted ShortcutDetector instance

required
Source code in shortcut_detect/reporting/report_builder.py
def __init__(self, detector: "ShortcutDetector"):
    """
    Initialize report builder.

    Args:
        detector: Fitted ShortcutDetector instance
    """
    if not detector.results_:
        raise ValueError("Detector must be fitted before generating reports")

    self.detector = detector
    self.results = detector.results_
    self.plots = {}  # Cache for generated plots
    self._reporters = [cls() for cls in REPORTER_CLASSES]
Functions
to_html
to_html(
    output_path: str, include_visualizations: bool = True
)

Generate interactive HTML report with visualizations.

Parameters:

Name Type Description Default
output_path str

Path to save HTML file

required
include_visualizations bool

Whether to include plots

True
Source code in shortcut_detect/reporting/report_builder.py
def to_html(self, output_path: str, include_visualizations: bool = True):
    """
    Generate interactive HTML report with visualizations.

    Args:
        output_path: Path to save HTML file
        include_visualizations: Whether to include plots
    """
    # Generate plots if needed
    if include_visualizations and not self.plots:
        print("Generating visualizations...")
        self.plots = generate_all_plots(self.detector)

    html_content = self._generate_html(include_visualizations)

    os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
    with open(output_path, "w") as f:
        f.write(html_content)

    print(f"✅ HTML report saved to: {output_path}")
to_csv
to_csv(output_dir: str) -> dict[str, str]

Export results to CSV files.

Parameters:

Name Type Description Default
output_dir str

Directory to save CSV files

required

Returns:

Type Description
dict[str, str]

Dictionary mapping file names to their paths

Source code in shortcut_detect/reporting/report_builder.py
def to_csv(self, output_dir: str) -> dict[str, str]:
    """
    Export results to CSV files.

    Args:
        output_dir: Directory to save CSV files

    Returns:
        Dictionary mapping file names to their paths
    """
    print("Exporting to CSV...")
    return export_to_csv(self.detector, output_dir)
to_pdf
to_pdf(
    output_path: str, include_visualizations: bool = True
)

Generate PDF report using weasyprint.

Parameters:

Name Type Description Default
output_path str

Path to save PDF file

required
include_visualizations bool

Whether to include plots

True
Source code in shortcut_detect/reporting/report_builder.py
def to_pdf(self, output_path: str, include_visualizations: bool = True):
    """
    Generate PDF report using weasyprint.

    Args:
        output_path: Path to save PDF file
        include_visualizations: Whether to include plots
    """
    self._ensure_homebrew_libs()
    try:
        from weasyprint import HTML
    except ImportError:
        warnings.warn(
            "weasyprint not installed. PDF generation requires weasyprint.\n"
            "Install with: uv pip install weasyprint\n"
            "On macOS also run: brew install pango\n"
            "Generating HTML instead...",
            stacklevel=2,
        )
        html_path = output_path.replace(".pdf", ".html")
        self.to_html(html_path, include_visualizations)
        print(f"📄 HTML generated at: {html_path}")
        print("To convert to PDF, install weasyprint: uv pip install weasyprint")
        return

    # Generate HTML content
    if include_visualizations and not self.plots:
        print("Generating visualizations...")
        self.plots = generate_all_plots(self.detector)

    # Remove 3D plot from PDF version due to interactivity issues
    # 1. Back up the original plots
    original_plots = self.plots

    # 2. Filter out the interactive 3D plot for the PDF version
    if include_visualizations:
        self.plots = {k: v for k, v in original_plots.items() if k != "html_3d"}

    try:
        # 3. Generate content using the filtered plots
        html_content = self._generate_html(include_visualizations)
    finally:
        # 4. Restore original plots
        self.plots = original_plots

    # Convert HTML to PDF
    os.makedirs(os.path.dirname(os.path.abspath(output_path)) or ".", exist_ok=True)
    print("Converting HTML to PDF...")
    HTML(string=html_content).write_pdf(output_path)

    print(f"✅ PDF report saved to: {output_path}")
to_markdown
to_markdown(
    output_path: str, include_visualizations: bool = False
)

Generate Markdown report summarizing detection results.

Parameters:

Name Type Description Default
output_path str

Path to save Markdown file

required
include_visualizations bool

Placeholder for API parity (plots not embedded)

False
Source code in shortcut_detect/reporting/report_builder.py
def to_markdown(self, output_path: str, include_visualizations: bool = False):
    """
    Generate Markdown report summarizing detection results.

    Args:
        output_path: Path to save Markdown file
        include_visualizations: Placeholder for API parity (plots not embedded)
    """
    content = self._generate_markdown()
    os.makedirs(os.path.dirname(os.path.abspath(output_path)) or ".", exist_ok=True)
    with open(output_path, "w") as f:
        f.write(content)
    print(f"✅ Markdown report saved to: {output_path}")

ReportBuilder

Constructor

ReportBuilder(
    title: str = "Shortcut Detection Report",
    include_visualizations: bool = True,
    theme: str = 'default'
)

Parameters

Parameter Type Default Description
title str "Shortcut Detection Report" Report title
include_visualizations bool True Include plots
theme str 'default' Report theme

Methods

add_section()

def add_section(
    title: str,
    content: str,
    visualizations: list = None
) -> ReportBuilder

Add a section to the report.

add_summary()

def add_summary(detector: ShortcutDetector) -> ReportBuilder

Add summary from ShortcutDetector results.

build_html()

def build_html(output_path: str) -> None

Generate HTML report.

build_pdf()

def build_pdf(output_path: str) -> None

Generate PDF report (requires WeasyPrint).

Usage

from shortcut_detect.reporting import ReportBuilder

# Create builder
builder = ReportBuilder(title="My Analysis Report")

# Add detector results
builder.add_summary(detector)

# Add custom sections
builder.add_section(
    title="Custom Analysis",
    content="Additional findings...",
    visualizations=[fig1, fig2]
)

# Generate reports
builder.build_html("report.html")
builder.build_pdf("report.pdf")

CSVExporter

Export detection results to CSV files.

Constructor

CSVExporter(output_dir: str = "exports")

Methods

export_all()

def export_all(detector: ShortcutDetector) -> list[str]

Export all results to CSV files.

Returns: List of created file paths.

export_statistical()

def export_statistical(results: dict, path: str) -> str

Export statistical test results.

export_probe()

def export_probe(results: dict, path: str) -> str

Export probe results.

Usage

from shortcut_detect.reporting import CSVExporter

exporter = CSVExporter(output_dir="./results")

# Export all results
files = exporter.export_all(detector)
print(f"Created: {files}")

# Export specific results
exporter.export_statistical(
    detector.statistical_results_,
    "statistical_results.csv"
)

Output Files

File Contents
summary.csv Overall risk assessment
hbac_results.csv HBAC metrics
probe_results.csv Probe accuracy, predictions
statistical_results.csv P-values, effect sizes
geometric_results.csv Bias direction, overlap
gradcam_mask_overlap_samples.csv Per-sample GradCAM vs. GT mask overlap metrics
cav_concept_scores.csv Per-concept CAV quality/TCAV scores and flags

Visualizations

Built-in Plots

The reporting module includes visualization helpers:

from shortcut_detect.reporting.visualizations import (
    plot_embedding_scatter,
    plot_volcano,
    plot_feature_importance,
    plot_group_distributions
)

# t-SNE/UMAP scatter plot
fig = plot_embedding_scatter(
    embeddings,
    group_labels,
    method='tsne'
)
fig.savefig("scatter.png")

# Volcano plot
fig = plot_volcano(
    pvalues=test.pvalues_corrected_,
    effect_sizes=test.effect_sizes_
)
fig.savefig("volcano.png")

Interactive Plots

For interactive visualizations:

from shortcut_detect.reporting.visualizations import (
    plot_3d_embedding,
    create_interactive_report
)

# 3D plot with Plotly
fig = plot_3d_embedding(embeddings, group_labels)
fig.write_html("3d_plot.html")

# Full interactive report
create_interactive_report(detector, "interactive_report.html")

Integration with ShortcutDetector

The simplest way to generate reports:

from shortcut_detect import ShortcutDetector

detector = ShortcutDetector(methods=['hbac', 'probe', 'statistical'])
detector.fit(embeddings, group_labels)

# Direct report generation
detector.generate_report("report.html", format="html")
detector.generate_report("report.pdf", format="pdf")

See Also