Run code when cells finished executing

141 views
Skip to first unread message

Adam Rule

unread,
Apr 4, 2017, 6:34:06 PM4/4/17
to Project Jupyter
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);
           
}
       
}
   
};

Thomas Kluyver

unread,
Apr 5, 2017, 10:11:36 AM4/5/17
to Project Jupyter
On 4 April 2017 at 23:34, Adam Rule <acr...@gmail.com> wrote:
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. 

Yeah, that's not uncommon with Javascript - lots of things are async, so a function may well return before the effect it's meant to produce has happened. Feel free to propose more events if the existing ones don't meet your needs - I don't think there's much cost to adding more events.
 
Looking through the code base I thought I could listen for finished_execute.CodeCell but that event never seems to fire.

That might be a bug - can you file an issue about it? And if you have time, try to track down why it might be going missing? And check that you've got the latest version of notebook - 5.0 was just released.

Thomas

Adam Rule

unread,
Apr 5, 2017, 11:55:49 AM4/5/17
to Project Jupyter
I'm running version 4.1.0 so I'll update to 5.0 and check if finished_execute.CodeCell gets thrown. If not, I'll file an issue.

Thomas Kluyver

unread,
Apr 5, 2017, 11:58:33 AM4/5/17
to Project Jupyter
On 5 April 2017 at 16:55, Adam Rule <acr...@gmail.com> wrote:
I'm running version 4.1.0 so I'll update to 5.0 and check if finished_execute.CodeCell gets thrown. If not, I'll file an issue.

Thanks Adam :-)

Adam Rule

unread,
Apr 6, 2017, 2:34:51 PM4/6/17
to Project Jupyter
Just to close the loop, finished_execute.CodeCell executes just fine in v. 5.0.0, so I can listen for that before scraping the notebook. I'm going to need to find another way to get the cell data for older versions of the notebook, though.

Jake Stewart

unread,
Oct 5, 2017, 9:05:41 AM10/5/17
to Project Jupyter

Hi Adam, 

Did you ever get a workaround for this for earlier versions of Jupyter?

Thanks

Jake

Adam Rule

unread,
Oct 5, 2017, 12:19:35 PM10/5/17
to Project Jupyter
It ended up being a bit of a hack. You can see the code here (https://github.com/activityhistory/nbcomet/blob/master/nbcomet/static/main.js#L333).

Essentailly if it is a run-cell action, I listen for the kernel_idle.Kernel event.
Reply all
Reply to author
Forward
0 new messages