Automation Report
Using the ReportBuilder, you can create a HTML report that can be sent via email or saved as a standalone documentation file.
It helps you to document the outcome of the automation process and provides a way to share the results with others.
It allows you to organize messages into sections and categorize them by status (success, warning, error, etc.).
Migration Guide
Since the version 3.30.0, the report builder is the recommended way to create and send reports.
The EmailNotifier is deprecated and will be removed in future version.
For creating the report builder, preferably use the report_builder() method, located in the BaseScenario class.
See the example below for the differences between the old and new approach.
import aiviro
class NewReportScenario(aiviro.BaseScenario):
def __init__(self, config: "YAMLConfig"):
super().__init__(config)
self.report = self.report_builder()
def _run(self):
try:
# Your automation logic here
self.report.successful("Task completed successfully")
except Exception as e:
self.report.error(f"Task failed: {str(e)}")
def section_example(self):
"""Example of creating a new section and adding messages to it."""
with self.report.create_section("Section Title", "Sub-title") as section:
section.successful("Task completed successfully")
def last_section_example(self):
"""Example of adding messages to the last created section."""
with self.report.last_section as section:
section.successful("Task completed successfully")
def message_styling_example(self):
"""Example of using Markdown in the messages."""
self.report.successful("Task completed successfully with **bold** and *italic* text")
self.report.warning("Task completed with warning, check [link](https://example.com) for more details")
def _after_run(self):
"""Example of sending the report via email client."""
self.send_report_via_email_client(self.config.recipients)
import aiviro
from aiviro.modules.notifier import Style, Item
class DeprecatedNotifierScenario(aiviro.BaseScenario):
def __init__(self, config: "YAMLConfig"):
super().__init__(config)
self.email_notifier = self.email_notifier()
def _run(self):
try:
# Your automation logic here
self.email_notifier.successful("Task completed successfully")
except Exception as e:
self.email_notifier.error(f"Task failed: {str(e)}")
def block_example(self):
"""Example of creating a new block and adding messages to it."""
notification_block = self.email_notifier.create_block("Block Title")
notification_block.successful("Task completed successfully")
def message_styling_example(self):
"""Example of using Style object to format the messages."""
self.email_notifier.default_block.item_style = Style(bold=True)
self.email_notifier.successful(Item("Task", "completed successfully"))
def last_block_example(self):
"""Example of adding messages to the last created block."""
self.email_notifier.last_block.successful("Task completed successfully")
def _after_run(self):
"""Example of sending the report via email client."""
if self.email_notifier.blocks:
self.email_notifier.send_report(self.config.recipients)
Report Builder
- class aiviro.core.services.report_service.ReportBuilder(title: str, run_id: str, start_time: datetime, message_titles: dict[LogStatus, str] | None = None, logging_level: str | None = None, metrics_to_display: list[str | MetricsNames] | None = None)
Builder for creating an HTML report, that can be sent via email. The report is used to describe the outcome of the automation process. It is split into multiple parts:
Header - contains title of the report, start time and duration
Summary - contains summary status of the run with short description of the status
Performance metrics - shows performance of the automation process in the last 14 days
Detailed summary - contains detailed summary, in form of sections of the run with all messages
Footer - contains link to report an issue, social media links and identifier of the run with product version
Note
The report builder supports Markdown highlighting in the messages & sub-messages.
Aiviro also supports localization of the report, it can be changed by setting the environment variable
aiviro.core.utils.localization.LOCALE_KEY.
Example of the generated HTML report.
- Parameters:
title – Title of the report
run_id – Unique identifier of the run
start_time – Start time of the run
message_titles – Custom titles for the messages, based on their status
logging_level – Logging level using which every message is logged, if not set no logging is performed
metrics_to_display – Set of sub-metrics to display in the performance metrics section. See
MetricsNamesfor available names. Include here also custom ones that are defined inaiviro.step()decorator.
- Example:
>>> import uuid >>> import datetime >>> import aiviro >>> >>> builder = aiviro.ReportBuilder( ... title="Invoice processing Workflow", ... run_id=uuid.uuid4().hex, ... start_time=datetime.datetime.now(), ... message_titles={ ... LogStatus.SUCCESS: "OK", ... LogStatus.ERROR: "Could not process", ... }, ... metrics_to_display=[MetricsNames.api_reader_pages, MetricsNames.email_extracted], ... ) >>> # adds message into default section >>> builder.successful("File **ENSEGT20250000689** was successfully uploaded") >>> builder.successful("File **ENSEGT20250000723** was successfully uploaded") >>> # creates new section >>> with builder.create_section("Goods dispatch") as g_section: ... g_section.unable_to_process(f"**Attachment:** no attachments") ... g_section.error( ... f"An unexpected error occurred in infor: {aiviro.Input('username')} not found in 15 seconds.", ... ) ... g_section.successful( ... "Order 'P245H0062', Receipt 'WR2434683', Vessel fee '65.05'", ... ) >>> # creates another section >>> email_section = builder.create_section( ... "Email processing - T-Mobile service statement for the period 1.6.2025 - 30.6.2025", ... "(billing group 55237596)" ... ) >>> with email_section as section: ... section.successful("**Attachment:** Invoice EU (CZ) 100250089.pdf") ... section.successful("Attachment: 20250150.pdf, Internal number: FPM-12525422") ... section.warning("Invoice number: 1018800725").add_sub_message( ... "The total price of the invoice does not match the price in the copied record" ... ) ... section.successful( ... "The invoice was successfully registered in Helios under the number INFD25/0999. [Helios link](https://aiviro.com)", ... )
- property last_section: ReportSectionManager
Returns section manager for the last created section.
- set_active_section(section_id: str) None
Sets active section.
- Parameters:
section_id – Identifier of the section
- generate_html_report(end_time: datetime, performance_metrics: PerformanceMetrics | ScenarioRunStats | None = None) str
Generates HTML report.
- Parameters:
end_time – End time of the run
performance_metrics – Performance metrics to include in the report
- create_section(title: str, sub_title: str | None = None, section_id: str | None = None) ReportSectionManager
Creates new section in the report.
- Parameters:
title – Title of the section
sub_title – Sub-title of the section
section_id – Identifier of the section, if not set title is used as identifier
- Returns:
SectionManager object, which can be used to add messages to the section
- custom(message: str, status: LogStatus, sub_messages: list[str] | None = None) LogEntry
Creates a message in the report with custom status.
- Parameters:
message – Main message of the report
status – Status of the message
sub_messages – List of sub-messages
- Returns:
LogEntry object, which represents the message in the report.
- inactive(message: str, sub_messages: list[str] | None = None) LogEntry
Creates an ‘inactive’ (gray) message in the report.
- Parameters:
message – Main message of the report
sub_messages – List of sub-messages
- successful(message: str, sub_messages: list[str] | None = None) LogEntry
Creates a ‘successful’ (green) message in the report.
- Parameters:
message – Main message of the report
sub_messages – List of sub-messages
- unable_to_process(message: str, sub_messages: list[str] | None = None) LogEntry
Creates an ‘unable to process’ (blue) message in the report.
- Parameters:
message – Main message of the report
sub_messages – List of sub-messages
- class aiviro.core.services.report_service.ReportSectionManager(builder: ReportBuilder, section_id: str)
Context manager for managing active section, enables writing into section using
withstatement.
- pydantic model aiviro.core.services.report_service.ReportSection
Represents a section in the report.
- class aiviro.core.services.report_service.LogStatus(value)
Represents the status for an individual LogEntry.
- INACTIVE = 0
Gray colored message for skipped or inactive items.
- SUCCESS = 10
Green colored message for successful operations.
- INFO = 20
Blue colored message for general information.
- WARNING = 30
Yellow colored message for non-critical issues.
- ERROR = 40
Red colored message for errors or failures.
- pydantic model aiviro.core.services.report_service.LogEntry
- pydantic model aiviro.core.services.report_service.PerformanceMetrics
- field sub_metrics: list[PerformanceSubMetric] [Optional]
- pydantic model aiviro.core.services.report_service.PerformanceSubMetric
- class aiviro.core.utils.metrics.constants.MetricsNames(value)
List of available default metrics.
- cache_usage = 'cache_usage'
Percentage of cache hits
- api_reader_documents = 'api_reader_documents'
Number of documents processed using Aiviro Reader
- api_reader_pages = 'api_reader_pages'
Number of pages processed using Aiviro Reader
- api_llm_usage = 'api_llm_usage'
Number of tokens used by LLM features
- email_extracted = 'email_extracted'
Number of emails extracted from mailbox
- email_sent = 'email_sent'
Number of emails sent
- pdf_processed = 'pdf_processed'
Number of PDFs processed
- actions_used = 'actions_used'
Number of actions used in the scenario