Display HTML in swift notebooks

I’m trying to the equivalent of

from IPython.display import display,HTML
out = display(HTML(some_html_code))

then later

out.update(HTML(some_new_html_code))

to work in jupyter notebook for swift (to port our progress bars there). For now

import Python
let display = Python.import("IPython.display")
var out = display.display(display.HTML(some_html_code))

gives me in the output

<IPython.core.display.HTML object>

which isn’t really what I would like to see. Any workaround this? @marcrasi

I will investigate why the HTML is not displaying.

Since you say you’re working on progress bars, there’s a limitation you should know about. Display messages (e.g. matplotlib plots, or this HTML stuff) only get sent to the client at the end of cell execution. If you want to have things appearing in the client during cell execution, you’ll have to print to stdout.

If updating an HTML display is very important to you, then I could implement a hacky workaround where stdouts containing a special magic string get displayed as HTML on the client.

(Details about this limitation: In order to send display messages during cell execution, we need to send ZMQ messages from the Swift process to Jupyter. To do this, we need to run the ZMQ library in the Swift process. The ZMQ library starts up its own threadpool for sending messages. LLDB (which has control over the Swift process) likes to halt these threads in sometimes, which prevents ZMQ from sending messages. So to remove this limitation, I’ll have to figure out why LLDB likes to halt the threads, and modify LLDB, and I think this might be quite difficult.)

3 Likes

Agh, that’s annoying. I can do a string progress bar with print statements, but the HTML version is way nicer (and has an HTML table with the stats, and even some graphs that get plotted during training). You can see an example running here.

So the HTML not displaying isn’t important per se if it doesn’t update during training.

@marcrasi to clarify - progress bars et al aren’t a priority compared to getting a flexible training loop and optimizers working. So it’s a nice to have, but we can absolutely do the lessons without it.

Longer term question: would Xeus help avoid these issues?

No, because Xeus would be a different way of invoking LLDB, but LLDB would be invoking and interacting with the Swift process in the same way as it does now.

I’ll put off doing anything with HTML or display updates until the more important stuff is working well :slight_smile:

1 Like

I guess a follow-up question is then, how to update a print to reprint on the same line, then.
If I do:

print(bar, terminator: "\r")

nothing gets printed at all. If I do

print("\r" + bar)

it prints all the successive progress bars.

import Glibc

for i in 0..<5 {
    print("\(i)", terminator:"\r")
    sleep(1)
    fflush(stdout)
}

Actually the sleep line should be the last in the loop, but you get the idea.

2 Likes

Thanks a lot!

Is it still true today that the only way to display output during execution is with printing? I’ve been trying the various things that StackOverflow suggests for live updating matplotlib with no success, and it looks like this might be why. I’m using Google Colab.

And is there a way to clear the output? The two suggestions I’m finding (clear_output() from IPython.display and print("\u{001B}[2J")) don’t seem to be working.

Google Colab provides google.colab.output which has a clear() function which works in Python, but doesn’t work in Swift.