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
Reportclass does not automatically escape HTML content that you provide tolog()orreplace(). 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 callget_tab()withcreate_if_missing=Falsefor a tab that does not exist, it will raise aValueError.
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.