Skip to main content

Generating Execution Reports

Generating Execution Reports

Execution reports provide a structured and navigable way to present information about processes, tests, or operations. The report generation system allows developers to create multi-tabbed HTML reports, dynamically add content, and render them for display or persistence.

Core Components

The report generation system is built around two primary components:

  • Report: The central object that represents the entire report. It manages a collection of tabs and orchestrates the final HTML rendering.
  • Tab: Represents a single section or page within a report. Each tab can accumulate or replace HTML content.

Creating and Managing Reports

To begin generating a report, instantiate the Report object. Each report can be given a descriptive name.

from your_module import Report # Assuming Report and Tab are in 'your_module'

# Create a new report
my_report = Report(name="My Execution Summary")

Accessing Tabs

A Report organizes its content into Tab objects. By default, every Report includes a main tab. You can access existing tabs or create new ones using the get_tab method.

# Access the default main tab
main_tab = my_report.get_tab("Main")

# Create a new tab for specific details
details_tab = my_report.get_tab("Detailed Logs")

# Attempting to get a non-existent tab without creation will raise an error
try:
non_existent_tab = my_report.get_tab("NonExistent", create_if_missing=False)
except ValueError as e:
print(e) # Output: Tab NonExistent does not exist.

Adding Content to Tabs

Tab objects are designed to hold HTML content. You can either append content incrementally or replace the entire tab's content.

Appending Content

Use the log method to append new HTML snippets to a tab. This is useful for building up a log of events or results over time.

# Add a simple paragraph to the main tab
main_tab.log("<p>Execution started successfully.</p>")

# Add a list item to the details tab
details_tab.log("<ul><li>Step 1: Data loaded.</li></ul>")

# Subsequent calls to log append to the existing content
details_tab.log("<ul><li>Step 2: Processing complete.</li></ul>")

Replacing Content

The replace method overwrites all existing content within a tab with a new HTML string. This is suitable for displaying final results, dynamic updates, or single-view outputs.

# Replace the entire content of the main tab with a summary table
main_tab.replace("<h2>Summary</h2><table><tr><th>Metric</th><th>Value</th></tr><tr><td>Duration</td><td>120s</td></tr></table>")

# Replace the details tab content with a final status message
details_tab.replace("<p>All detailed logs have been processed and summarized.</p>")

When providing content to log or replace, ensure it is a valid HTML string. The content is inserted directly into a div element within the final report.

Generating the Final Report

Once all content has been added to the desired tabs, generate the complete HTML report using the get_final_report method of the Report object.

# Get the final HTML string of the report
final_html_report = my_report.get_final_report()

# If running in an IPython environment (e.g., Jupyter notebook),
# this method automatically returns an IPython.display.HTML object
# for rich display. Otherwise, it returns a raw HTML string.

The generated HTML includes navigation elements for switching between tabs. You can save this HTML string to a file for later viewing:

# Save the report to an HTML file
with open("execution_report.html", "w") as f:
f.write(final_html_report)

Customizing Report Appearance

The report generation system uses an internal HTML template to structure the final output. You can customize the report's overall look and feel by providing a custom template path when initializing the Report object.

The default template expects two placeholders: NAV_HTML for the tab navigation and BODY_HTML for the content of the active tab. Your custom template must include these placeholders for the report to render correctly.

import pathlib

# Assuming you have a custom_template.html file
custom_template_path = pathlib.Path("path/to/your/custom_template.html")

# Create a report using a custom template
custom_report = Report(name="Custom Report", template_path=custom_template_path)

# Add content as usual
custom_report.get_tab("Info").log("<p>This report uses a custom layout.</p>")

# Generate and view the report
custom_report_html = custom_report.get_final_report()

Important Considerations

HTML Safety

The report generation system directly embeds the HTML content provided to Tab.log and Tab.replace into the final report without sanitization. It is the developer's responsibility to ensure that all HTML content added to tabs is safe and does not contain malicious scripts or vulnerabilities (e.g., Cross-Site Scripting - XSS). Always sanitize user-generated or untrusted HTML before adding it to a report.

Content Structure

While tabs accept any valid HTML, structuring content logically within each tab enhances readability. Consider using standard HTML elements like headings (<h1>, <h2>), paragraphs (<p>), lists (<ul>, <ol>), and tables (<table>) to organize information effectively.