Converting to (not from) ipython Notebook format Converting to (not from) ipython Notebook format python python

Converting to (not from) ipython Notebook format


Since the code in the accepted answer does not work anymore, I have added this self-answer that shows how to import into a notebook with the current (v4) API.

Input format

Versions 2 and 3 of the IPython Notebook API can import a python script with special structuring comments, and break it up into cells as desired. Here's a sample input file (original documentation here). The first two lines are ignored, and optional. (In fact, the reader will ignore coding: and <nbformat> lines anywhere in the file.)

# -*- coding: utf-8 -*-# <nbformat>3.0</nbformat># <markdowncell># The simplest notebook. Markdown cells are embedded in comments, # so the file is a valid `python` script. # Be sure to **leave a space** after the comment character!# <codecell>print("Hello, IPython")# <rawcell># Raw cell contents are not formatted as markdown

(The API also accepts the obsolete directives <htmlcell> and <headingcell level=...>, which are immediately transformed to other types.)

How to import it

For some reason, this format is not supported by version 4 of the Notebook API. It's still a nice format, so it's worth the trouble to support it by importing into version 3 and upgrading. In principle it's just two lines of code, plus i/o:

from IPython.nbformat import v3, v4with open("input-file.py") as fpin:    text = fpin.read()nbook = v3.reads_py(text)nbook = v4.upgrade(nbook)  # Upgrade v3 to v4jsonform = v4.writes(nbook) + "\n"with open("output-file.ipynb", "w") as fpout:    fpout.write(jsonform)

But not so fast! In fact, the notebook API has a nasty bug: If the last cell in the input is a markdown cell, v3.reads_py() will lose it. The simplest work-around is to tack on a bogus <markdown> cell at the end: The bug will delete it, and everyone is happy. So do the following before you pass text to v3.reads_py():

text += """# <markdowncell># If you can read this, reads_py() is no longer broken! """


The following works for IPython 3, but not IPython 4.

The IPython API has functions for reading and writing notebook files. You should use this API and not create JSON directly. For example, the following code snippet converts a script test.py into a notebook test.ipynb.

import IPython.nbformat.current as nbfnb = nbf.read(open('test.py', 'r'), 'py')nbf.write(nb, open('test.ipynb', 'w'), 'ipynb')

Regarding the format of the .py file understood by nbf.read it is best to simply look into the parser class IPython.nbformat.v3.nbpy.PyReader. The code can be found here (it is not very large):

https://github.com/ipython/ipython/blob/master/jupyter_nbformat/v3/nbpy.py

Edit: This answer was originally written for IPyhton 3. I don't know how to do this properly with IPython 4. Here is an updated version of the link above, pointing to the version of nbpy.py from the IPython 3.2.1 release:

https://github.com/ipython/ipython/blob/rel-3.2.1/IPython/nbformat/v3/nbpy.py

Basically you use special comments such as # <codecell> or # <markdowncell> to separate the individual cells. Look at the line.startswith statements in PyReader.to_notebook for a complete list.


very old question, i know. but there is jupytext (also available on pypi) that can convert from ipynb to several formats and back.

when jupytext is installed you can use

$ jupytext --to notebook test.py

in order to generate test.ipynb.

jupytext has a lot more interesting features that can come in handy when working with notebooks.


here is a more recent question on that topic.