# Source code for the system (must be in one cell)
# See below for documentation
#NBINCLUDE_STOP
try:
nbinclude
except NameError: # nbinclude is not defined
def nbinclude(nbfile, root=nbinclude_f.name):
global __name__
import io
import IPython.nbformat.current
import os
# Find the notebook file
if not nbfile.endswith(".ipynb"):
nbfile = nbfile + ".ipynb"
if not os.path.isfile(nbfile):
candidate = os.path.join(os.getcwd(), nbfile)
if os.path.isfile(candidate):
nbfile = candidate
else:
candidate = os.path.join(get_ipython().config.NotebookManager.notebook_dir, nbfile)
if os.path.isfile(candidate):
nbfile=candidate
else:
candidate = os.path.join(os.path.dirname(root), nbfile)
if os.path.isfile(candidate):
nbfile = candidate
if not os.path.isfile(nbfile):
raise IOError, 'Notebook "{}" not found'.format(nbfile)
# Read it
with io.open(nbfile) as f:
nb = IPython.nbformat.current.read(f, 'json')
# Execute the cells in it
ip = get_ipython()
old_name = __name__
__name__ = os.path.basename(nbfile).split(".ipynb")[0].replace(" ", "")
for cell in nb.worksheets[0].cells:
if cell.cell_type != 'code':
continue
inp = cell.input
stop = False
if "#NBINCLUDE_STOP" in inp:
inp = inp.split("#NBINCLUDE_STOP")[0]
stop = True
ip.run_cell(inp)
if stop:
break
__name__ = old_name
This system is designed to let you include an IPython notebook file from another IPython notebook file.
To set up, first download this nbinclude.ipynb
file to your system.
Then add the following shim to the beginning of your notebook files, substituting the path as appropriate.
# Cross-notebook include shim
with open("/home/nikita/dev/ipython-notebooks/nbtools/nbinclude.ipynb") as nbinclude_f: # don't rename nbinclude_f
import IPython.nbformat.current
get_ipython().run_cell(IPython.nbformat.current.read(nbinclude_f, 'json').worksheets[0].cells[0].input)
Then you can start including notebooks. The following all work:
# Searches for notebooks relative to the following locations:
# 1. As absolute path
# 2. Relative to the current working directory
# 3. Relative to the default notebook folder
# 4. Relative to the folder that contains nbinclude.ipynb
nbinclude("nbinclude.ipynb")
# Omitting the ".ipynb" works, too
nbinclude("nbinclude")
# So do absolute paths
nbinclude("/home/nikita/dev/ipython-notebooks/nbtools/nbinclude.ipynb")
# And absolute paths that omit the ".ipynb"
nbinclude("/home/nikita/dev/ipython-notebooks/nbtools/nbinclude")
To have code run only in the standalone notebook, the classic guard works:
if __name__ == "__main__":
print "This code will not run if the notebook is imported via nbinclude"
There is also a magic macro, #NBINCLUDE_STOP
(exact spelling). The remainder of the cell containing the macro, and any cells after it, will not be read by the nbinclude system.
This is useful for separating cells at the beginning of the notebook (which contain function definitions you want to include), from cells at the end of the notebook (that you don't want to include)