Hi! Anyone knows if it's possible to keep cards af...
# ask-metaflow
m
Hi! Anyone knows if it's possible to keep cards after a step failed? For example the following works and I'm able to view the html card from
start
on the UI.
Copy code
@card(type="html")
@catch(var="error")
@step
def start(self):
    self.html = """<h1>hello world</h1>"""
    raise Exception("boom!")
    self.next(self.end)

def end(self):
    if self.error:
        raise self.error
However the problem is I can't retry that step on argo because as
start
has the catch it didn't fail. The step that fails is
end
I would like to do something like this
Copy code
@card(type="html")
@step
def start(self):
    self.html = """<h1>hello world</h1>"""
    raise Exception("boom!")
Or like this where
start
step fails but already produced cards are accesible through metaflow UI.
Copy code
@card
@step
def start(self):
    current.card.append(HTMLCard(html=html))
    raise Exception("boom!")
b
Do you know what version of the metaflow-ui you are using?
The latest version https://github.com/Netflix/metaflow-ui/releases/tag/v1.3.9 shows cards even if the task failed. This was a change introduced with the dynamic cards functionality and differs from previous version of metaflow-ui
m
we are using 1.1.4
oh! thank you! I'll update the version
I can't manage to make it work with this @brave-lion-15961
Copy code
from metaflow.cards import Markdown
from metaflow import (
    FlowSpec,
    card,
    current,
    project,
    step,
)


@project(name="dnn")
class TestFlow(FlowSpec):

    @card
    @step
    def start(self):
        current.card.append(Markdown("Hello World"))
        import time
        time.sleep(2)
        1/0
        self.next(self.end)

    @step
    def end(self):
        print("Done")


if __name__ == "__main__":
    TestFlow()
metaflow UI knows there is some card attached, but is unable to load it
h
Hey Alvaro! With the new dynamic cards functionality in the latest release of metaflow, you can run
current.card.refresh()
to ensure the card is created. Cards are by default created when tasks end but to ensure that they are present during task execution, you can just drop a
current.card.refresh()
during task execution. you need to change your flow to
Copy code
from metaflow.cards import Markdown
from metaflow import (
    FlowSpec,
    card,
    current,
    project,
    step,
)


@project(name="dnn")
class TestFlow(FlowSpec):

    @card
    @step
    def start(self):
        current.card.append(Markdown("Hello World"))
        import time
        current.card.refresh()      
        time.sleep(2)
        1/0
        self.next(self.end)

    @step
    def end(self):
        print("Done")


if __name__ == "__main__":
    TestFlow()
m
AWESOME! thank you!
I'll give it a try with the html card
But I think it needs some work as only works as decorator
h
For the HTML card you can do something like :
Copy code
from metaflow import FlowSpec, card, step, current

from datetime import datetime

class HTMLCardFlow(FlowSpec):

    @card(type='html')
    @step
    def start(self):
        HTML = """
        <html>
        <body style="background: #FF5733; font-family: sans-serif; margin: 150px">
            <h1 style="color: white">Time is {time}</h1>
        </body>
        </html>
        """
        t = datetime.now().isoformat()
        current.card.refresh({'html': HTML.format(time=t)})
        self.next(self.end)

    @step
    def end(self):
        pass

if __name__ == '__main__':
    HTMLCardFlow()
👍 1