2

I want to write a code in a Jupyerlab notebook that runs other cells without the user doing anything. I found the solution:

from IPython.display import Javascript
Javascript('JupyterLab.notebook.execute_cells_below()')

But it doesn't seem to work in JupyterLab, it throws the error:

Javascript Error: notebook is not defined

Is there any similar way to do it using JupyterLab?

2 Answers2

1

Maybe you can set a shortcut for 'run all cells above' and execute the following lines:

import keyboard

keyboard.press_and_release('your_shorcut_here')

Let's say that you've defined your shortcut as shift+s. Just put it in the code above as strig:

keyboard.press_and_release('shift+s')

For the latest jupyter notebook, (version 5) you can go to the 'help' tab in the top of the notebook and then select the option 'edit keyboard shortcuts' and add in your own customized shortcut.

Probably there is the same option for jupyter lab.

Henrique Branco
  • 1,778
  • 1
  • 13
  • 40
1

I found out how to execute cells programmatically when writing a JupyterLab extension. This is not exactly what you asked for but might help others searching for this topic. The code for JupyterLab seems to be more complex than for JupyterNotebook.

JupyterLab comes with the method

NotebookActions.run(notebook, sessionContext);

which executes the currently selected cells. There are a few other methods (e.g. "runAllBelow"), too. Also see

https://github.com/jupyterlab/jupyterlab/blob/master/packages/notebook/src/actions.tsx

Some example code (also see my JupyterLab extension for treezjs):

var { NotebookActions } = require("@jupyterlab/notebook");    
var app = ... //injected with activate method of extension

var pythonCode = 'print("Hello World")';

this.__notebookPanel = this.__getFirstVisibleNotebookPanel(app);

executePythonCodeWithCell(pythonCode)

async executePythonCodeWithCell(pythonCode){
    
    var self=this;

    var NotebookActions = this.__dependencies['NotebookActions'];

    return new Promise(async (resolve, reject) => {

        if(self.__notebookPanel){
            var notebook = self.__notebookPanel.content;
            var notebookModel = notebook.model;
            var sessionContext = self.__notebookPanel.sessionContext;   
            
            var options = { };
            var cellModel = notebookModel.contentFactory.createCell('code',options);                
            cellModel.value.text = pythonCode;

            const activeCellIndexBackup = notebook.activeCellIndex;

            
            var newCellIndex = notebookModel.cells.length;
            notebookModel.cells.insert(newCellIndex, cellModel);                
            notebook.activeCellIndex = newCellIndex;

            var cell = notebook.activeCell;
            
            try{
                await NotebookActions.run(notebook, sessionContext);
            } catch(error){
                reject(error);
            } 
            
            var htmlArray = [];

            for(var output of cell.outputArea.node.children){                               
                htmlArray.push(output.innerHTML);
            }                   
           
            await NotebookActions.deleteCells(notebook);
            
            notebook.activeCellIndex = activeCellIndexBackup;

            resolve(htmlArray);     

        }               
        
    });     
}

__getFirstVisibleNotebookPanel(app){
        var mainWidgets = app.shell.widgets('main');
        var widget = mainWidgets.next();
        while(widget){
            var type = widget.constructor.name;
            if(type == 'NotebookPanel'){  //other wigets might be of type DocumentWidget
                if (widget.isVisible){
                    return widget;
                }
            }
            widget = mainWidgets.next();
        }
        return null;
}

Part of my old code for JupyterNotebook:

this.__notebook = Jupyter.notebook;

async executePythonCodeWithCell(pythonCode){
    
    var self=this;

    return new Promise(function(resolve, reject) {  
        
        var cell = self.__notebook.insert_cell_below();
        cell.element[0].style.display = 'none';
        cell.set_text(pythonCode);
        cell.events.on('finished_execute.CodeCell', (event, data) => self.__codeCellExecutionFinished(cell, data.cell, resolve));

        try{
            cell.execute();
        } catch(error){
            reject(error);
        } 
        
    });     
}

Related:

JupyterLab: Run all cells below

https://github.com/jupyterlab/jupyterlab/issues/6563

https://github.com/CDAT/jupyter-vcdat/blob/master/src/CellUtilities.ts

https://github.com/stefaneidelloth/treezjs/blob/master/jupyter_lab_extension/jupyterLabTerminal.js

Stefan
  • 10,010
  • 7
  • 61
  • 117
  • Could you please let me know how can I integrate it into my own JupyterLab? – akkab Jul 30 '21 at 04:07
  • Does https://jupyterlab.readthedocs.io/en/stable/user/extensions.html and https://github.com/stefaneidelloth/treezjs/blob/master/doc/installation/jupyterLabInstallation.md answer your question? – Stefan Jul 30 '21 at 06:40