I am creating a button that runs a job when clicked using ipywidgets all inside of a Jupyter Notebook. This job can take some long amount of time, so I would like to also give the user the ability to stop the job.
I've created a minimally reproducible example that runs for only 10 seconds. All of the following is run from a Jupyter Notebook cell:
import ipywidgets as widgets
from IPython.display import display
from time import sleep
button = widgets.Button(description='run job')
output = widgets.Output()
def abort(event):
with output:
print('abort!')
def run_job(event):
with output:
print('running job')
button.description='abort'
button.on_click(run_job, remove=True)
button.on_click(abort)
sleep(10)
print('job complete!')
button.on_click(run_job)
display(button, output)
If the user clicks 'run job', then waits 2 seconds, then clicks 'abort'. The behavior is:
running job
job complete!
abort!
Which implies the 'abort' event fires after the job is already complete. I would like the print sequence to be:
running job
abort!
job complete!
If the abort can fire immediately when clicked, then I have a way to actually stop the job inside of my class objects.
How can I get the abort event to run immediately when clicked from a Jupyter Notebook?