Button that controls another jupyter cell

155 views
Skip to first unread message

lafont...@gmail.com

unread,
May 18, 2018, 8:27:51 AM5/18/18
to Project Jupyter

I have a simple question. I am using Jupyter Notebook (with Python) and I would like simply creates a button that could pause some code. Something like if the button is pressed continue to run a for loop, if not then stop.

I tried with the following simple code but when I click on the toggle button there is no effect on the value. Actually if it could work even between twi Jupyter cells it would be the best. Can you help me?



import ipywidgets as w
import time
import threading


toggle = w.ToggleButton(description='click here')
display (toggle)


def worker():
       print(toggle.value)



for i in range(5):
    t = threading.Thread(target=worker)
    time.sleep(1)
    t.start()

Travis DePrato

unread,
May 19, 2018, 5:49:06 AM5/19/18
to jup...@googlegroups.com, lafont...@gmail.com
The reason this doesn't work is because of the inherent sequential-and-blocking-ness of code execution in the Jupyter kernel protocol. The short version of this is that the kernel doesn't see your button toggle until after the loop finishes.

Details: the kernel has a couple of different sockets, two of which are relevant:
  • shell: this is a request/reply socket where the requests are (usually) code execution requests. When one request is executing, the next request won't be answered until the first finishes.
  • iopub: this is a publisher socket that broadcasts when (for instance) data is printed
So what happens is this:
  1. You execute the cell: the notebook sends an execute request to the kernel.
  2. The kernel becomes "busy" and won't process incomming execution requests until the current one is finished.
  3. The button is displayed (this is broadcast via iopub).
  4. You enter the loop.
  5. You press the "stop button" which queues an execution request on the shell channel, but the kernel is busy and so won't handle it yet.
  6. The loop finishes (after the final sleep and Thread.start) and the kernel becomes "idle."
  7. The kernel sees the queued execution request on the shell channel and becomes "busy" again.
  8. The ipywidgets backend handles the request and switches the value of "toggle".
  9. The ipywidgets handler finishes and the kernel becomes "idle" again.
The best workaround, as far as I know, is to interrupt the kernel (the equivalent of Ctrl + C in a terminal) which will raise a KeyboardInterrupt exception that your code could handle appropriately. This is in the Kernel menu of the notebook.

As an (important) aside, threading in the kernel is potentially a huge pitfall. Once you enter threads and multiprocessing, the kernel (and notebook) is no longer able to tell what output originated from what code/execution request. For example, if you start a thread with a loop that prints "hello" and waits a second forever, the kernel will go back to "idle" with that thread still running (since the synchronous part of the code you submitted is over). The notebook (and this is an implementation detail of the notebook) will associate the output from that thread with the most recently executed cell. Example attached.Screenshot from 2018-05-19 05-43-42.png

If you're really tied to doing it that way, you could start the loop in a thread. This will break if you try to execute a new cell while the thread is running, however, and if at all possible, interrupts are your best bet.

Screenshot from 2018-05-19 05-46-46.png

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+u...@googlegroups.com.
To post to this group, send email to jup...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/fd9231a4-6e93-4851-8630-0266a60ca194%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Travis DePrato (he/him/his, they/them/theirs)
University of Michigan, Ann Arbor
Computer Science & Engineering
Mathematics (Discrete and Algorithmic Methods)

Jason Grout

unread,
May 19, 2018, 9:20:11 PM5/19/18
to jup...@googlegroups.com, lafont...@gmail.com
Travis, I just wanted to compliment you on your very thoughtful and complete answer, addressing not only the technical aspects of the original question, but going beyond it to address common pitfalls. It looked like it took some time to put that together, and I really appreciate you taking the time to do it. Thanks!

Of course, I'm not the one that asked the question--they may still have follow-up questions. I just wanted to say I really enjoyed reading your response.

Jason

P.S. Technically clicking the button sends a comm message, not an 'execute_request' message per se, but that doesn't change the substance of what you've said.


Damián Avila

unread,
May 21, 2018, 8:58:47 AM5/21/18
to jup...@googlegroups.com, lafont...@gmail.com
I just wanted to say I really enjoyed reading your response. 

I had the very same experience reading Travis's response. 

Thanks, Travis!!

To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscribe@googlegroups.com.

To post to this group, send email to jup...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/fd9231a4-6e93-4851-8630-0266a60ca194%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Travis DePrato (he/him/his, they/them/theirs)
University of Michigan, Ann Arbor
Computer Science & Engineering
Mathematics (Discrete and Algorithmic Methods)

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscribe@googlegroups.com.

To post to this group, send email to jup...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Damián Avila

Fabien Lafont

unread,
May 22, 2018, 4:19:48 AM5/22/18
to damia...@gmail.com, jup...@googlegroups.com
Wow, indeed Travis that's a whole wikipedia article! 

Thanks a lot!

Fabien

To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+u...@googlegroups.com.

To post to this group, send email to jup...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/fd9231a4-6e93-4851-8630-0266a60ca194%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Travis DePrato (he/him/his, they/them/theirs)
University of Michigan, Ann Arbor
Computer Science & Engineering
Mathematics (Discrete and Algorithmic Methods)

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+u...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+u...@googlegroups.com.

To post to this group, send email to jup...@googlegroups.com.



--
Damián Avila

Tony Hirst

unread,
May 22, 2018, 8:22:58 AM5/22/18
to Project Jupyter
As a slight aside to this, there is this extension - https://github.com/micahscopes/nbmultitask - that allows (control of) multitasking / mutliple threads spawned from within a single notebook

--tony
Reply all
Reply to author
Forward
0 new messages