Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I programatically add cells to and IPython or Jupyter notebook?

This question has been asked a few times before, however the accepted answers suggest that the asker was looking to do something different to me.

I am trying to create an IPython widget that creates and runs a new cell. The purpose of this is to provide a similitude between the widget and the IPython cells.

For example: I would like to have a SelectorWidget that fills and runs the next cell with 'cell magic'.

But I am facing the problem that (please correct me if I am wrong) IPython does not keep an internal data-structure of cells.

It seems to me that the only way to modify a new cell is with:

In [1]: get_ipython().set_next_input('1')

In [2]: 1

I'd just like to be able to run that line automatically. But I don't think that's possible with set_next_input given it's just a hack on top of readline.


I can do what I want to do with:

 display(Javacript('''
 
 var code = IPython.notebook.insert_cell_at_bottom('code'))
 code.execute()

 '''))

But it just feels so incredibly wrong to be driving input that way as it depends on a web-browser to do something quite simple. And you're depending on an external event loop.

The equivalent to doing this on the command line would be starting a background thread/process/corountine that has access to the IPython prompt's stdin and that would accept tasks from the foreground thread to write to the forground thread's own stdin. It's possible to do but has the same problem as the Jupyter methodology because it's specific to the input mechanism of IPython.

like image 636
Rol Avatar asked Oct 21 '25 04:10

Rol


1 Answers

Looking at the problem, I can't seem to find a fully synchronous method without JavaScript either.

I have found the run_cell and run_cell_magic work to avoid the JavaScript example but fail on producing the cell with the outputs.

The closest I could come to was:

from IPython import get_ipython

def make_cell_run_code(code):
    ipython = get_ipython()
    ipython.set_next_input(code)
    ipython.run_cell(code)

code = "print('test')"
make_cell_run_code(code)

which avoids the JavaScript but still has cells out of sync.

With JavaScript, we can use negative indexing to ensure the same cell is excecuted.

from IPython.display import Javascript, display

def create_and_excecute_code_cell(code=''):
    display(Javascript("""
        var code = IPython.notebook.insert_cell_at_bottom('code');
        code.set_text("{0}");
        Jupyter.notebook.execute_cells([-1]);
    """.format(code)))

create_and_excecute_code_cell("%time x=0")

Which I cribbed from here. Your JavaScript snippet didn't work for me.

Other avenues are to look deeper into IPython.core.interactiveshell.InteractiveShell

like image 164
chsws Avatar answered Oct 23 '25 20:10

chsws



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!