ipython-contrib / jupyter_contrib_nbextensions

A collection of various notebook extensions for Jupyter
http://jupyter-contrib-nbextensions.readthedocs.io/en/latest
Other
5.24k stars 807 forks source link

What IPython.events get triggerd after a code cell being runned and result returned? #664

Open cqcn1991 opened 8 years ago

cqcn1991 commented 8 years ago

I want to make a small extention after a code cell is executed and the output_wrapper HTML is returned. However, how do I know related javascript events so I can bind my function to it?

Formerly, I played with the toc2 extension, in which the function bind to

      $([IPython.events]).on("rendered.MarkdownCell", function(){
        ### toc2 function
    });

Now I want to know what should replace "rendered.MarkdownCell", when the code cell is executed and result returned.


I find a event "execute.CodeCell", however, this is not enough. I need to locate which code cell is executed and do some thing with its output. Is there any relavant API?

jcb91 commented 8 years ago

I fear it's not simple - I had problems doing this with the execute_time extension, as events got delayed from one cell execution's end until the next cell started running. I ended up patching the shell reply callback to get reliable execution at the correct time, so it might be worth looking at the source for that. Alternatively, you could listen for a kernel_idle.Kernel event, having stored a reference to the cell from the 'execute.CodeCell event. This was the previous mo for execute_time, but it had problems whereby the cells queued for execution by the notebook could get out of sync with what the extension thought was happening.

For investigating events in general, I sometimes add the following to my custom.js, which logs all events to the console (probably best to remove when not in use!)

define([
    "require",
    'base/js/events'
], function (require, events) {
    var all_events = [
        'app_initialized.DashboardApp',
        'app_initialized.NotebookApp',
        'autosave_disabled.Notebook',
        'autosave_enabled.Notebook',
        'before_save.Notebook',
        'changed',
        'checkpoint_created.Notebook',
        'checkpoint_delete_failed.Notebook',
        'checkpoint_deleted.Notebook',
        'checkpoint_failed.Notebook',
        'checkpoint_restore_failed.Notebook',
        'checkpoint_restored.Notebook',
        'checkpoints_listed.Notebook',
        'collapse_pager',
        'command_mode.Cell',
        'command_mode.Notebook',
        'config_changed.Editor',
        'create.Cell',
        'delete.Cell',
        'draw_notebook_list.NotebookList',
        'edit_mode.Cell',
        'edit_mode.Notebook',
        'execute.CodeCell',
        'execution_request.Kernel',
        'expand_pager',
        'file_load_failed.Editor',
        'file_loaded.Editor',
        'file_renamed.Editor',
        'file_saved.Editor',
        'file_saving.Editor',
        'input_reply.Kernel',
        'kernel_autorestarting.Kernel',
        'kernel_busy.Kernel',
        'kernel_connected.Kernel',
        'kernel_connection_dead.Kernel',
        'kernel_connection_failed.Kernel',
        'kernel_created.Kernel',
        'kernel_created.Session',
        'kernel_dead.Kernel',
        'kernel_dead.Session',
        'kernel_disconnected.Kernel',
        'kernel_idle.Kernel',
        'kernel_interrupting.Kernel',
        'kernel_killed.Kernel',
        'kernel_killed.Session',
        'kernel_ready.Kernel',
        'kernel_reconnecting.Kernel',
        'kernel_restarting.Kernel',
        'kernel_starting.Kernel',
        'kernelspecs_loaded.KernelSpec',
        'list_checkpoints_failed.Notebook',
        'mode_changed.Editor',
        'no_kernel.Kernel',
        'notebook_copy_failed',
        'notebook_deleted.NotebookList',
        'notebook_load_failed.Notebook',
        'notebook_loaded.Notebook',
        'notebook_loading.Notebook',
        'notebook_read_only.Notebook',
        'notebook_renamed.Notebook',
        'notebook_restoring.Notebook',
        'notebook_save_failed.Notebook',
        'notebook_saved.Notebook',
        'open_with_text.Pager',
        'output_appended.OutputArea',
        'preset_activated.CellToolbar',
        'preset_added.CellToolbar',
        'rebuild.QuickHelp',
        'received_unsolicited_message.Kernel',
        'rendered.MarkdownCell',
        'resize',
        'resize-header.Page',
        'save_status_clean.Editor',
        'save_status_dirty.Editor',
        'select.Cell',
        'selected_cell_type_changed.Notebook',
        'send_input_reply.Kernel',
        'sessions_loaded.Dashboard',
        'set_dirty.Notebook',
        'set_next_input.Notebook',
        'shell_reply.Kernel',
        'spec_changed.Kernel',
        'spec_match_found.Kernel',
        'spec_not_found.Kernel',
        'trust_changed.Notebook',
        'unrecognized_cell.Cell',
        'unrecognized_output.OutputArea',
        'unregistered_preset.CellToolbar',
    ];
    events.on(all_events.join(' '), function (evt, data) {
        console.log('[evt]', evt.type, (new Date()).toISOString(), data);
    });
});

I got the events list by searching notebook source for the regex (?<=\btrigger\()(['"])([^'"])+\1

cqcn1991 commented 8 years ago

@jcb91 I'm a little bit confused. So it's really hard to know when a codecell is executed and finished running?

jcb91 commented 8 years ago

It depends what you're trying to achieve. If you want to know when the cell's execution finishes at the time when it finishes, as with the execute_time extension, then yes, I found that that was difficult to do reliably. If you just want to edit the output html, then maybe you could hook into the output_appended.OutputArea event. What are you actually trying to do?

cqcn1991 commented 8 years ago

@jcb91 I want to output and then hide the cell's output, something like this hide_as

This is because sometimes I need to output intermediate numbers, but thet take too much space in notebook. So I want to hide them, and when I want the result I can check them.

cqcn1991 commented 8 years ago

But I think this is not very intersting. I think what we really need to build is a workspace/variable explorer. That is much better to check the variables.

jfbercher commented 8 years ago

In case it helps: https://github.com/ipython/ipywidgets/blob/master/docs/source/examples/Variable%20Inspector.ipynb (install ipywidgets and download the notebook in order to test ithis)

cqcn1991 commented 8 years ago

@jfbercher Yes, I actually asked this before (https://github.com/ipython-contrib/IPython-notebook-extensions/issues/623), but I'm not capable of making it into a usable one right now, it's too hard.

jfbercher commented 8 years ago

ok ok I am late to the party

jcb91 commented 8 years ago

@cqcn1991 right, so you want a kind of toggleable print statement in lieu of a variable inspector. I take it the regular output-collapsing is insufficient. The hide output option from the runtools extension seems to do pretty much exactly what you want - hides/shows the output of a single cell. Am I missing something?

cqcn1991 commented 8 years ago

@jcb91 I have just looked at runtools (https://github.com/ipython-contrib/IPython-notebook-extensions/tree/5c7dc53f0bf2ca2bd67a57519bfc98c6a8135528/nbextensions/usability/runtools).

The reason I wanto output and then hide is that I may want to see some calculation result during a certain procedure. But they normally takes too much space. For example, in https://cdn.rawgit.com/cqcn1991/Wind-Speed-Analysis/master/output_HTML/marham.html#5.3-Sectoral-Comaprison, there is a df,

2016-07-15 19 32 58

I output it to see the curve's specific value. But in most cases, I don't need it, the curve plot is enough, so I want to hide it after output.

However, as I said above. This problem could be solved much more beautifully if we have an variable explorer. So when I need the result, I check them directly without outputing them manually.