Hello,
I am writing both a notebook extension and a server extension to track changes to notebooks over time. How can I run code after an action has been applied?
In the notebook extension, I'm attempting to execute blocks of code both before and after Jupyter performs certain actions (e.g., 'run-cell-and-select-next', 'split-cell-at-cursor') so that I can track how these actions affect the notebook. My problem is that some actions seem to call code that runs asynchronously and my post-application block runs before the action has been applied.
For example, when I call var mod = this.env.notebook.toJSON(); to get the sate of the notebook after the run-cell-and-select-next action has been called, the kernal has often not finished executing the code or rendering the output.
Looking through the
code base I thought I could listen for
finished_execute.CodeCell but that event never seems to fire.
I include my code below.
function patch_actionHandler_call(){
/* Inject code into the actionhandler to track desired actions */
console.log('[Comet] patching ActionHandler.prototype.call');
var old_call = ActionHandler.__proto__.call;
ActionHandler.__proto__.call = function (){
var actionName = arguments[0].split(":")[1]; // remove 'jupter-notebook:' prefix
if(actions_to_intercept.indexOf(actionName)>-1){
// get time, action name, and selected cell(s) before action applied
var t = Date.now();
var selectedIndex = this.env.notebook.get_selected_index();
var selectedIndices = this.env.notebook.get_selected_cells_indices();
// let the notebook apply the action
old_call.apply(this, arguments);
// now get the modified notebook and its url
var mod = this.env.notebook.toJSON();
var notebookUrl = this.env.notebook.notebook_path;
var baseUrl = this.env.notebook.base_url;
var url = utils.url_path_join(baseUrl, 'api/comet', notebookUrl);
// and send the data to the server extension for processing
sendData(t, actionName, selectedIndex, selectedIndices, mod, url);
}
else{
old_call.apply(this, arguments);
}
}
};