Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion dev-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ IPython
keyrings.alt
setuptools_scm
pytest-icdiff
jinja2

# Tensorflow is not available for python 3.12 yet: https://github.com/tensorflow/tensorflow/issues/62003
tensorflow; python_version<'3.12'
Expand Down
6 changes: 0 additions & 6 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,6 @@ jaraco-functools==4.0.1
# via keyring
jedi==0.19.1
# via ipython
jinja2==3.1.4
# via
# -r dev-requirements.in
# flytekit
jmespath==1.0.1
# via botocore
joblib==1.4.2
Expand All @@ -220,8 +216,6 @@ markdown-it-py==3.0.0
# via
# flytekit
# rich
markupsafe==2.1.5
# via jinja2
marshmallow==3.21.2
# via
# dataclasses-json
Expand Down
31 changes: 16 additions & 15 deletions flytekit/deck/deck.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import enum
import os
import typing
from html import escape
from string import Template
from typing import Optional

from flytekit.core.context_manager import ExecutionParameters, ExecutionState, FlyteContext, FlyteContextManager
Expand Down Expand Up @@ -153,8 +155,16 @@ def _get_deck(
If ignore_jupyter is set to True, then it will return a str even in a jupyter environment.
"""
deck_map = {deck.name: deck.html for deck in new_user_params.decks}
nav_htmls = []
body_htmls = []

raw_html = get_deck_template().render(metadata=deck_map)
for key, value in deck_map.items():
nav_htmls.append(f'<li onclick="handleLinkClick(this)">{escape(key)}</li>')
# Can not escape here because this is HTML. Escaping it will present the HTML as text.
# The renderer must ensure that the HTML is safe.
body_htmls.append(f"<div>{value}</div>")

raw_html = get_deck_template().substitute(NAV_HTML="".join(nav_htmls), BODY_HTML="".join(body_htmls))
if not ignore_jupyter and ipython_check():
try:
from IPython.core.display import HTML
Expand Down Expand Up @@ -184,18 +194,9 @@ def _output_deck(task_name: str, new_user_params: ExecutionParameters):
logger.error(f"Failed to write flyte deck html with error {e}.")


def get_deck_template() -> "Template":
from jinja2 import Environment, FileSystemLoader, select_autoescape

def get_deck_template() -> Template:
root = os.path.dirname(os.path.abspath(__file__))
templates_dir = os.path.join(root, "html")
env = Environment(
loader=FileSystemLoader(templates_dir),
# 🔥 include autoescaping for security purposes
# sources:
# - https://jinja.palletsprojects.com/en/3.0.x/api/#autoescaping
# - https://stackoverflow.com/a/38642558/8474894 (see in comments)
# - https://stackoverflow.com/a/68826578/8474894
autoescape=select_autoescape(enabled_extensions=("html",)),
)
return env.get_template("template.html")
templates_dir = os.path.join(root, "html", "template.html")
with open(templates_dir, "r") as f:
template_content = f.read()
return Template(template_content)
10 changes: 2 additions & 8 deletions flytekit/deck/html/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,14 @@

</head>
<body>
<!---{#% autoescape true %#}--->
<nav id="flyte-frame-nav">
<ul id="flyte-frame-tabs">
{% for key, value in metadata.items() %}
<li onclick="handleLinkClick(this)">{{ key | safe }}</li>
{% endfor %}
$NAV_HTML
</ul>
</nav>
<div id="flyte-frame-container">
{% for key, value in metadata.items() %}
<div>{{ value | safe }}</div>
{% endfor %}
$BODY_HTML
</div>
<!---{#% autoescape %#}--->
</body>
<script>
const setTabs = index => {
Expand Down
14 changes: 5 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ dependencies = [
"grpcio",
"grpcio-status",
"importlib-metadata",
"jinja2",
"joblib",
"jsonlines",
"jsonpickle",
Expand All @@ -41,7 +40,7 @@ dependencies = [
"pygments",
"python-json-logger>=2.0.0",
"pytimeparse>=1.1.8",
"pyyaml!=6.0.0,!=5.4.0,!=5.4.1", # pyyaml is broken with cython 3: https://github.com/yaml/pyyaml/issues/601
"pyyaml!=6.0.0,!=5.4.0,!=5.4.1", # pyyaml is broken with cython 3: https://github.com/yaml/pyyaml/issues/601
"requests>=2.18.4",
"rich",
"rich_click",
Expand Down Expand Up @@ -96,7 +95,7 @@ norecursedirs = ["common", "workflows", "spark", "fsspec"]
log_cli = true
log_cli_level = 20
markers = [
"sandbox_test: fake integration tests", # unit tests that are really integration tests that run on a sandbox environment
"sandbox_test: fake integration tests", # unit tests that are really integration tests that run on a sandbox environment
"serial: tests to avoid using with pytest-xdist",
"hypothesis: tests that use they hypothesis library",
]
Expand Down Expand Up @@ -134,10 +133,7 @@ lint.ignore = [
# Do not assign a lambda expression, use a def
"E731",
]
extend-exclude = [
"tests/",
"**/tests/**",
]
extend-exclude = ["tests/", "**/tests/**"]

[tool.ruff.lint.extend-per-file-ignores]
"*/__init__.py" = [
Expand All @@ -146,5 +142,5 @@ extend-exclude = [
]

[tool.codespell]
ignore-words-list="ot,te,raison,fo,lits"
skip="./docs/build,./.git,*.txt"
ignore-words-list = "ot,te,raison,fo,lits"
skip = "./docs/build,./.git,*.txt"