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