Skip to main content

Creating a Basic Report

Creating Your First Report with flyte-sdk

This tutorial guides you through the process of creating a basic report using flyte-sdk. By the end, you will be able to instantiate a Report object, add content to different tabs, and generate a final HTML file.

Prerequisites

To follow this tutorial, you need to have flyte-sdk installed in your Python environment.

pip install flyte-sdk

Step 1: Instantiate a Report

The first step is to create an instance of the Report class. The Report class is the central component for aggregating content into a structured, tabbed HTML output. When you instantiate it, you must provide a name for your report. Based on the Report class definition, the name attribute is set after instantiation.

Let's create a report named "My First Report":

from report import Report

# Instantiate a new report
my_report = Report()
my_report.name = "My First Report"

print(f"Report created: {my_report.name}")

When a Report object is initialized, it automatically creates a default "main" tab. This tab is where content will be added if no other tab is explicitly specified.

Step 2: Add Content to the Main Tab

You can add HTML content to the report's tabs. The Report class provides a get_tab method to retrieve a Tab object, and the Tab object has log and replace methods to manage its content. The _MAIN_TAB_NAME constant defines the name of the default tab.

Let's add some simple HTML content to the main tab:

from report import Report
from report._report import _MAIN_TAB_NAME

my_report = Report()
my_report.name = "My First Report"

# Get the main tab and log content to it
main_tab = my_report.get_tab(_MAIN_TAB_NAME)
main_tab.log("<h1>Welcome to My Report!</h1>")
main_tab.log("<p>This is some initial content in the main tab.</p>")

print(f"Content added to the \'{_MAIN_TAB_NAME}\' tab.")

The log() method appends the new content to any existing content within that tab. If you need to overwrite the tab's content, you would use the replace() method instead.

Step 3: Create and Add Content to a New Tab

Reports can have multiple tabs to organize different sections of information. You can create new tabs simply by calling get_tab() with a new name. If the tab doesn't exist, get_tab() will create it by default.

Let's add a new tab called "Details" and put some content there:

from report import Report
from report._report import _MAIN_TAB_NAME

my_report = Report()
my_report.name = "My First Report"
main_tab = my_report.get_tab(_MAIN_TAB_NAME)
main_tab.log("<h1>Welcome to My Report!</h1>")
main_tab.log("<p>This is some initial content in the main tab.</p>")

# Create a new tab and add content
details_tab = my_report.get_tab("Details")
details_tab.log("<h2>Detailed Information</h2>")
details_tab.log("<p>Here are some more specific details about the report.</p>")

# Overwrite content in the new tab
details_tab.replace("<p>This content has been replaced!</p>")

print("Content added and replaced in the 'Details' tab.")

Notice how replace() completely overwrites the previous content of the "Details" tab.

Step 4: Generate the Final HTML Report

Once you have added all your content to the various tabs, you can generate the complete HTML output of your report using the get_final_report() method. This method combines all tab contents into a single HTML string, structured according to the internal template.

from report import Report
from report._report import _MAIN_TAB_NAME
import pathlib

my_report = Report()
my_report.name = "My First Report"
main_tab = my_report.get_tab(_MAIN_TAB_NAME)
main_tab.log("<h1>Welcome to My Report!</h1>")
main_tab.log("<p>This is some initial content in the main tab.</p>")

details_tab = my_report.get_tab("Details")
details_tab.log("<h2>Detailed Information</h2>")
details_tab.log("<p>Here are some more specific details about the report.</p>")
details_tab.replace("<p>This content has been replaced!</p>")

# Generate the final HTML report
final_html = my_report.get_final_report()

# Save the HTML to a file
output_file = pathlib.Path("my_first_report.html")
with open(output_file, "w") as f:
f.write(final_html)

print(f"Report saved to {output_file.absolute()}")

After running this code, you will find a file named my_first_report.html in your current directory. Opening this file in a web browser will display your report with the "main" and "Details" tabs.

Complete Working Example

Here is the complete code combining all the steps:

from report import Report
from report._report import _MAIN_TAB_NAME
import pathlib

# 1. Instantiate a new report
my_report = Report()
my_report.name = "My First Report"

# 2. Add content to the main tab
main_tab = my_report.get_tab(_MAIN_TAB_NAME)
main_tab.log("<h1>Welcome to My Report!</h1>")
main_tab.log("<p>This is some initial content in the main tab.</p>")

# 3. Create a new tab and add content
details_tab = my_report.get_tab("Details")
details_tab.log("<h2>Detailed Information</h2>")
details_tab.log("<p>Here are some more specific details about the report.</p>")

# Overwrite content in the new tab
details_tab.replace("<p>This content has been replaced!</p>")

# 4. Generate the final HTML report and save it
final_html = my_report.get_final_report()

output_file = pathlib.Path("my_first_report.html")
with open(output_file, "w") as f:
f.write(final_html)

print(f"Report \'{my_report.name}\' saved to {output_file.absolute()}")

Customizing the Report Template

The Report class uses an internal HTML template (_template.html) to structure the final output. You can customize the appearance of your reports by providing a custom template path during instantiation:

from report import Report
import pathlib

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

# Instantiate the report with a custom template
my_custom_report = Report()
my_custom_report.name = "Custom Report"
my_custom_report.template_path = custom_template_path

# ... add content and generate report as before ...

Important Considerations

  • HTML Escaping: The Report class does not automatically escape HTML content that you provide to log() or replace(). It is your responsibility to ensure that any HTML you add is safe and does not introduce vulnerabilities like Cross-Site Scripting (XSS).
  • get_tab(name, create_if_missing=False): If you call get_tab() with create_if_missing=False for a tab that does not exist, it will raise a ValueError.

Next Steps

Now that you can create basic reports, explore how to integrate flyte-sdk reports within Flyte tasks to generate dynamic reports based on your workflow executions. You can also delve into the structure of the default _template.html to understand how to create your own custom templates for more advanced styling and layout.