Alex
Alex

Reputation: 44305

How to reload a jupyter notebook after a kernel restart?

In a jupyter notebook I would like to define a function in python, which, when called, does the following:

Or as an alternative:

I have tried the following code

from IPython.display import display, HTML

def reload():
    display(HTML(
        '''
            <script>
                alert('This notebook needs to be restarted!');

                IPython.notebook.kernel.restart(); 
                IPython.display.clear_output();

                window.location.reload();

            </script>            
        '''
    ))
reload()

but it gives an error

AttributeError: 'function' object has no attribute 'clear_output'

despite this documentation.

When I remove the line

IPython.display.clear_output();

then the kernel is restarted, but I get 2(!) alerts and it looks like that the execution of the next cell is performed. Also, the cells are not cleared , the current cell still does have the star in the brackets ([*]).

How to do it correctly?

Upvotes: 1

Views: 3394

Answers (2)

Bacon Cow
Bacon Cow

Reputation: 1

I'm not sure to the other issues that you have encountered but the code

IPython.display.clear_output();

ran successfully without problems in my jupyter notebook, are you sure your jupyter notebook version is up to date or is the same version to that in the documentation? It is not surprising that different versions may have different function name or even the whole structure may varies.

Upvotes: -1

Jonathan Feenstra
Jonathan Feenstra

Reputation: 2779

This code does what you described as the alternative option, with the addition of saving a checkpoint before reloading so the output stays cleared:

from IPython.display import Javascript, display


def reload():
    display(
        Javascript('''
            // clear all output (based on: https://stackoverflow.com/a/47315713/9504155)           
            // save a reference to the cell we're currently executing inside of,
            // to avoid clearing it later (which would remove this js)
            var this_cell = $(element).closest('.cell').data('cell');
            function clear_other_cells () {
                Jupyter.notebook.get_cells().forEach(function (cell) {
                    if (cell.cell_type === 'code' && cell !== this_cell) {
                        cell.clear_output();
                    }
                    Jupyter.notebook.set_dirty(true);
                });
            }

            if (Jupyter.notebook._fully_loaded) {
                // notebook has already been fully loaded, so clear now
                clear_other_cells();
            }

            // save checkpoint so output stays cleared after reload
            IPython.notebook.save_checkpoint();

            IPython.notebook.kernel.restart();

            alert('This notebook needs to be restarted!');
            window.location.reload(false);
        '''))

reload()

If you prefer the first option (without reloading the page, focusing on the next cell instead) just remove the lines for saving a checkpoint and reloading and use the IPython.display.clear_output() function after the JavaScript part to clear the current cell's output as well:

from IPython.display import Javascript, clear_output, display


def reload():
    display(
        Javascript('''
            // clear all output (based on: https://stackoverflow.com/a/47315713/9504155)           
            // save a reference to the cell we're currently executing inside of,
            // to avoid clearing it later (which would remove this js)
            var this_cell = $(element).closest('.cell').data('cell');
            function clear_other_cells () {
                Jupyter.notebook.get_cells().forEach(function (cell) {
                    if (cell.cell_type === 'code' && cell !== this_cell) {
                        cell.clear_output();
                    }
                    Jupyter.notebook.set_dirty(true);
                });
            }

            if (Jupyter.notebook._fully_loaded) {
                // notebook has already been fully loaded, so clear now
                clear_other_cells();
            }

            IPython.notebook.kernel.restart();

            alert('Notebook output cleared!');
        '''))
    clear_output()

IPython.display.clear_output(); was not working in your code because it was called in the HTML <script> tag as JavaScript code instead of in Python.

Upvotes: 2

Related Questions