programmatically add cells to an ipython notebook for report generation

Below is the code of the function which will load contents of a file and insert it into the next cell of the notebook:

from IPython.display import display_javascript

def make_cell(s):
   text = s.replace('\n','\\n').replace("\"", "\\\"").replace("'", "\\'")
   text2 = """var t_cell = IPython.notebook.get_selected_cell()
   t_cell.set_text('{}');
   var t_index = IPython.notebook.get_cells().indexOf(t_cell);
   IPython.notebook.to_code(t_index);
   IPython.notebook.get_cell(t_index).render();""".format(text)
   display_javascript(text2, raw=True)

def insert_file(filename):
   with open(filename, 'r') as content_file:
       content = content_file.read()
   make_cell(content)

See details in my blog.


I won't judge whether it's a good idea, but if you call get_ipython().set_next_input(s) in the notebook, it will create a new cell with the string s. This is what IPython uses internally for its %load and %recall commands.


Note that the accepted answer by Tal is a little deprecated and getting more deprecated: in ipython v3 you can (/should) import nbformat directly, and after that you need to specify which version of notebook you want to create.

So,

from IPython.nbformat import current as nbf

becomes

from nbformat import current as nbf

becomes

from nbformat import v4 as nbf

However, in this final version, the compatibility breaks because the write method is in the parent module nbformat, where all of the other methods used by Fernando Perez are in the v4 module, although some of them are under different names (e.g. new_text_cell('markdown', source) becomes new_markdown_cell(source)).

Here is an example of the v3 way of doing things: see generate_examples.py for the code and plotstyles.ipynb for the output. IPython 4 is, at time of writing, so new that using the web interface and clicking 'new notebook' still produces a v3 notebook.


There's a Notebook gist by Fernando Perez here that demonstrates how to programmatically create new cells. Note that you can also pass metadata in, so if you're generating a report and want to turn the notebook into a slideshow, you can easily indicate whether the cell should be a slide, sub-slide, fragment, etc.

You can add any kind of cell, so what you want is straightforward now (though it probably wasn't when the question was asked!). E.g., something like this (untested code) should work:

from IPython.nbformat import current as nbf

nb = nbf.new_notebook()

cells = []

for var in my_list:
    # Assume make_image() saves an image to file and returns the filename
    image_file = make_image(var)
    text = "Variable: %s\n![image](%s)" % (var, image_file)
    cell = nbf.new_text_cell('markdown', text)
    cells.append(cell)

nb['worksheets'].append(nbf.new_worksheet(cells=cells))

with open('my_notebook.ipynb', 'w') as f:
        nbf.write(nb, f, 'ipynb')