googlecolab / colabtools

Python libraries for Google Colaboratory
Apache License 2.0
2.2k stars 722 forks source link

Updating a widget in the background not working #3373

Open agorskih opened 1 year ago

agorskih commented 1 year ago

Asynchronous Widgets not working properly in Colab, but works in other environments, like Binder. Example code at https://ipywidgets.readthedocs.io/en/8.0.2/examples/Widget%20Asynchronous.html#Updating-a-widget-in-the-background

import threading
from IPython.display import display
import ipywidgets as widgets
import time
progress = widgets.FloatProgress(value=0.0, min=0.0, max=1.0)

def work(progress):
    total = 100
    for i in range(total):
        time.sleep(0.2)
        progress.value = float(i+1)/total

thread = threading.Thread(target=work, args=(progress,))
display(progress)
thread.start()

Describe the current behavior Asynchronous Widget does not update.

Describe the expected behavior Asynchronous Widget updates.

What web browser you are using Safari

Additional context

cperry-goog commented 1 year ago

tracked internally at b/302541800

jagapiou commented 5 months ago

I've noticed that while this thread runs, if you run progress.send_state() in another cell, then the progress bar will update. So I think the value is being updated on the backend but for some reason it isn't being synced to the frontend.

jagapiou commented 5 months ago

OK here's my workaround. I use a Javascript setInterval to routinely trigger a refresh callback every 100ms.

from google.colab import output

output.register_callback('refresh', progress.send_state)

js = IPython.display.Javascript('''
var intervalId = setInterval(colab.kernel.invokeFunction, 100, 'refresh', []);
''')
IPython.display.display(js)