<@U06RKAMK0UC> one of my Flyte tasks produces a st...
# ask-ai
s
@ancient-wolf-19325 one of my Flyte tasks produces a standalone HTML file. Is there an easy way to use this file as a deck?
a
Yes, you can use the Flyte Decks feature to render your standalone HTML file as a deck. Flyte Decks allow you to generate static HTML reports associated with any of the outputs materialized within your tasks. You can use the
Deck.append
method to include your HTML content in a deck. Here's a basic example of how to achieve this: 1. Create a Flyte task: Ensure your task generates the HTML file. 2. Append the HTML file to a Deck: Use the
Deck.append
method to include the HTML content in a deck.
Copy code
import flytekit
from flytekit import task, workflow

@task
def generate_html() -> str:
    # Your logic to generate the HTML file
    html_content = "<html><body><h1>Hello, Flyte!</h1></body></html>"
    return html_content

@task
def create_deck(html_content: str):
    deck = flytekit.Deck("example_deck")
    deck.append(html_content)

@workflow
def my_workflow():
    html_content = generate_html()
    create_deck(html_content=html_content)

if __name__ == "__main__":
    my_workflow()
This example demonstrates how to generate an HTML file and append it to a Flyte Deck. You can then view the deck in the Flyte UI. Would you like more details or a more specific example? Sources: - Flyte Decks Documentation - Flyte Deck.append Method 👍 1 button 👎 0 button 💡 Hint: Mention @ancient-wolf-19325 in the thread for followups.
s
@ancient-wolf-19325 it is working, however, the deck is not nested in the Flyte GUI, but a file download pops up. Is there a way to fix it?
a
The issue you're encountering is likely due to the way the HTML content is being handled by the Flyte UI. This can happen if the HTML content is not properly rendered or if the Flyte UI is not configured to display the deck inline. To ensure the HTML content is rendered correctly in the Flyte UI, you can try the following steps: 1. Ensure Proper MIME Type: Make sure the HTML content is correctly identified as HTML. This can be done by using the
HTMLPage
type from
flytekit.types.file
. 2. Use the Correct Renderer: Ensure that the HTML content is being rendered using the appropriate renderer in Flyte. Here's an updated example that uses the
HTMLPage
type:
Copy code
import flytekit
from flytekit import task, workflow
from flytekit.types.file import HTMLPage

@task
def generate_html() -> HTMLPage:
    # Your logic to generate the HTML file
    html_content = "<html><body><h1>Hello, Flyte!</h1></body></html>"
    html_file = HTMLPage(content=html_content)
    return html_file

@task
def create_deck(html_file: HTMLPage):
    deck = flytekit.Deck("example_deck")
    deck.append(html_file)

@workflow
def my_workflow():
    html_file = generate_html()
    create_deck(html_file=html_file)

if __name__ == "__main__":
    my_workflow()
This example ensures that the HTML content is treated as an
HTMLPage
, which should help the Flyte UI render it correctly. Would you like more details or further assistance? Sources: - https://github.com/flyteorg/flyte/issues/5574 - https://discuss.flyte.org/t/10957373/a-question-about-deck-when-i-click-the-flyte-deck-button-in-/ 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
s
@ancient-wolf-19325 HTMLPage has no
content
parameter.
a
You are correct. The
HTMLPage
type in Flyte does not have a
content
parameter. Instead, it is used to denote files with an HTML extension. You should write the HTML content to a file and then return that file as an
HTMLPage
. Here's an updated example that writes the HTML content to a file and returns it as an `HTMLPage`:
Copy code
import os
from flytekit import task, workflow
from flytekit.types.file import HTMLPage

@task
def generate_html() -> HTMLPage:
    # Your logic to generate the HTML file
    html_content = "<html><body><h1>Hello, Flyte!</h1></body></html>"
    file_path = "/tmp/hello_flyte.html"
    with open(file_path, "w") as f:
        f.write(html_content)
    return HTMLPage(path=file_path)

@task
def create_deck(html_file: HTMLPage):
    deck = flytekit.Deck("example_deck")
    with open(html_file.path, "r") as f:
        deck.append(f.read())

@workflow
def my_workflow():
    html_file = generate_html()
    create_deck(html_file=html_file)

if __name__ == "__main__":
    my_workflow()
This example writes the HTML content to a file and returns it as an
HTMLPage
. The
create_deck
task then reads the content of the HTML file and appends it to the deck. Would you like more details or further assistance? Sources: - https://github.com/flyteorg/flytekit/blob/master/flytekit/types/file/__init__.py - https://discuss.flyte.org/t/15484282/hi-all-flyte-rookie-here-maybe-you-can-help-me-out-i-m-tryin/ Note: I wasn’t able to find highly relevant data sources, but above are a few potentially relevant links. 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
s
@ancient-wolf-19325 this also does not work, it seems that the argument to
append()
needs to be a string:
Copy code
Traceback (most recent call last):

      File "/epis/venv/lib/python3.10/site-packages/flytekit/exceptions/scopes.py", line 242, in user_entry_point
        return wrapped(*args, **kwargs)
      File "/workflows/demo.py", line 82, in validate_model
        deck.append(report_html)
      File "/epis/venv/lib/python3.10/site-packages/flytekit/deck/deck.py", line 61, in append
        assert isinstance(html, str)

Message:

    AssertionError: 

User error.
a
The error indicates that the
append
method of the
Deck
class expects a string containing HTML content. You need to read the HTML content from the file and pass it as a string to the
append
method. Here's the corrected example:
Copy code
import os
from flytekit import task, workflow
from flytekit.types.file import HTMLPage

@task
def generate_html() -> HTMLPage:
    # Your logic to generate the HTML file
    html_content = "<html><body><h1>Hello, Flyte!</h1></body></html>"
    file_path = "/tmp/hello_flyte.html"
    with open(file_path, "w") as f:
        f.write(html_content)
    return HTMLPage(path=file_path)

@task
def create_deck(html_file: HTMLPage):
    deck = flytekit.Deck("example_deck")
    with open(html_file.path, "r") as f:
        html_content = f.read()
    deck.append(html_content)

@workflow
def my_workflow():
    html_file = generate_html()
    create_deck(html_file=html_file)

if __name__ == "__main__":
    my_workflow()
This example writes the HTML content to a file, returns it as an
HTMLPage
, and then reads the content of the HTML file and appends it to the deck as a string. Would you like more details or further assistance? Sources: - https://github.com/flyteorg/flyte/issues/2175 - https://docs.flyte.org/en/latest/api/flytekit/generated/flytekit.deck.Deck.html 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
s
In case someone wanders here, when Azure object storage is used, content type of
deck.html
is not set to
text/html
.