Can a Jupyter notebook programmatically halt itself?

4,269 views
Skip to first unread message

Jeremy Douglass

unread,
Nov 8, 2016, 2:43:01 PM11/8/16
to Project Jupyter
Can a Jupyter notebook programmatically halt itself, such that it no longer appears in the "Running" tab?

At the end of a notebook "Run All", I would like the last notebook cell to contain code, and for that code to trigger the equivalent of:
  • the "Running tab > Shutdown notebook" action
  • ...or, failing that, the "Close and Halt" menu item
  • ...or, failing that, the "Kernel > Interrupt" menu item
Can this be done with javascript, or with %magic, or something else?

I am running the Docker image Jupyer Datascience Notebook, not JupyterHub.

I have tried to review related information, but none of these answered my question:

In certain use cases, idle notebook cruft is a huge problem. Information isn't exposed that makes identifying an idle notebook easier, and tools for culling notebooks are still wishlist items -- the consensus is it is hard to define idle, and hard to intervene with the browser in certain ways (e.g. event-on-tab-close).

I'm trying to cut the gordian knot by having a run-all notebook explicitly declare the notebook is halted / interrupted / done / closed as its last act. This seems like it should be possible, as it is a consequence of a user action (Run).

Is it possible? Or are there other ways of accomplishing this?


Thomas Kluyver

unread,
Nov 9, 2016, 11:20:33 AM11/9/16
to Project Jupyter
I don't think there's a great way to do exactly that. If you want to run notebooks unsupervised, you can do so in a headless fashion with 'jupyter nbconvert --execute', which will start a kernel, run the notebook and stop the kernel again.

We are planning to expose more information so you can see how long a notebook has been idle.

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/9b9d0a4e-b5f9-44b6-8504-1918bea15590%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Peter Parente

unread,
Nov 9, 2016, 11:22:53 AM11/9/16
to Project Jupyter
Hi Jeremy,

For a Python kernel, try this in the last cell:

%%javascript
Jupyter.notebook.session.delete();

It's borrowed from https://github.com/jupyter/notebook/blob/master/notebook/static/notebook/js/menubar.js#L225. The additional close_window logic in the notebook code probably won't work in the cell because the action is not directly triggered by a user click.

Cheers,
Pete

Jeremy Douglass

unread,
Nov 9, 2016, 11:25:30 AM11/9/16
to jup...@googlegroups.com
Thank you, Thomas.

So, even in theory, the JavaScript that fires on the Close & Halt button could not be called by injecting %%javascript ?


You received this message because you are subscribed to a topic in the Google Groups "Project Jupyter" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jupyter/3zAVHofQykg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jupyter+unsubscribe@googlegroups.com.

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

Jeremy Douglass

unread,
Nov 9, 2016, 11:26:37 AM11/9/16
to jup...@googlegroups.com
Thank you Peter! I will try and report back.
--
You received this message because you are subscribed to a topic in the Google Groups "Project Jupyter" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jupyter/3zAVHofQykg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jupyter+unsubscribe@googlegroups.com.
To post to this group, send email to jup...@googlegroups.com.

Jeremy Douglass

unread,
Nov 10, 2016, 2:57:13 PM11/10/16
to Project Jupyter
Thank you again for advice on this.

I am now able to programmatically halt notebooks -- this is really helpful for our multiuser workflow environment.

I created a test notebook (attached).

-  On "Run All" the final %%javascript cell "Jupyter.notebook.session.delete();" correctly stops the notebook.
-  The notebook interface shows "No Kernel", the Running tab no longer lists the notebook.
-  The previous cell still incorrectly shows a running status [ * ], however the output has returned.

Restart the notebook with:

-  Menu > Kernel > Restart ... "Dead Kernel" warning > Try restarting now
-  ...or refresh the browser tab.

Jeremy Douglass

unread,
Nov 10, 2016, 2:58:58 PM11/10/16
to Project Jupyter
Attaching the test notebook here.
shutdown-test.ipynb

Peter Parente

unread,
Nov 10, 2016, 4:21:38 PM11/10/16
to Project Jupyter
Thanks for writing back letting others know it worked, Jeremy!

Pete

Jeremy Douglass

unread,
Nov 13, 2016, 12:47:24 PM11/13/16
to Project Jupyter
I have a follow-up question.

Now that we are successfully halting notebooks when they finish running. The "No Kernel" message is subtle; in order to better inform users that their notebook is halted (and should either be closed or restarted) I am using a modal popup as per "Dialog popup in Jupyter notebook" (http://stefaanlippens.net/jupyter-notebook-dialog.html) that says "NOTEBOOK HALTED" and offers a "Restart Kernel" button.

Currently, the %%javascript cell successfully halts the notebook and displays the popup.

I would like to have the dialog button trigger a kernel restart with Jupyter.notebook.session.restart(). That command works fine in a %%javascript cell on its own and correctly restarts the kernel. However, adding that command to the dialog button does nothing. I am not a Javascript programmer, and may be making a very basic error. Any suggestions?

This is the cell at the end of a notebook that halts the kernel and displays the restart dialog:

%%javascript
require(
    ["base/js/dialog"], 
    function(dialog) {
        dialog.modal({
                title: 'Notebook halted!',
                body: 'This notebook is no longer running; the kernel has been halted. To continue working, restart the kernel.',
                buttons: {
                    'Kernel restart': { function(){Jupyter.notebook.session.restart();} }
                }
        });
    }
);
Jupyter.notebook.session.delete();

Jeremy Douglass

unread,
Nov 15, 2016, 5:03:36 PM11/15/16
to Project Jupyter
Still trying to get the Jupyter modal dialog to execute a Jupyter.notebook.session.restart() -- if that is possible.

I believe I found the modal dialog:
...however github linked API is missing.

Thomas Kluyver

unread,
Nov 15, 2016, 6:16:03 PM11/15/16
to Project Jupyter
Are you using Jupyterlab or the existing notebook? Those APIs are all part of Jupyterlab (the in-development new notebook interface). The existing interface has modal dialogs built with jquery and bootstrap, I think:

https://github.com/jupyter/notebook/blob/master/notebook/static/base/js/dialog.js

Jeremy Douglass

unread,
Nov 15, 2016, 9:11:59 PM11/15/16
to Project Jupyter
Ah -- I am using the regular notebook, not jupyterlab, so it looks like I was looking in the wrong place. Thank you for the link -- that looks really promising:

Jeremy Douglass

unread,
Nov 15, 2016, 9:17:08 PM11/15/16
to Project Jupyter
Well, that fixed it; I was just missing the "click" method keyword.

For anyone who finds it helpful, here it is:


Notebook Halt / Restart cell
 
When included at the bottom of a notebook, it will stop the notebook at the end of Run All, and pop up a modal dialog letting the user know that the notebook was auto-stopped at the end of the run. The dialog offers a "Kernel Restart" button which restarts the notebook.


%%javascript
require(
   
["base/js/dialog"],
   
function(dialog) {
        dialog
.modal({

                title
: 'Notebook Halted',
                body
: 'This notebook is no longer running; the kernel has been halted. Close the browser tab, or, to continue working, restart the kernel.',
                buttons
: {
                   
'Kernel restart': { click: function(){ Jupyter.notebook.session.restart(); } }
               
}
       
});
   
}
);
Jupyter.notebook.session.delete();
Reply all
Reply to author
Forward
0 new messages