In [ ]:
# See below the first header for documentation
# The code until then is bootstrap. It relies on an excessive number of hacks
# Do not allow the remainder of this file to be imported using the "import" statement
# The bootstrap process is designed for nbinclude instead of the import statement
#NBIMPORT_STOP
# This first cell is the only one run using the three-line nbinclude shim
try:
nbinclude
except NameError:
# Define nbinclude, if it is not already defined
# Uses the variable "nbinclude_f" to get the path to "nbinclude.ipynb", so it can
# be added to the module search path
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"
# Hacky notebook-finder. TODO: replace with the less hacky version below
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
# Now that nbinclude is available, we can run the remainder of this notebook until NBINCLUDE_STOP
nbinclude("nbinclude")
This code sets up the python import
statement for use with notebooks
It has been borrowed from: http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/Notebook/Importing%20Notebooks.ipynb
Now that everything has been set up, don't let nbinclude read any farther into the documentation part of the file
In [ ]:
#NBINCLUDE_STOP
This system allows importing and including IPython notebooks from other IPython notebooks.
Quite naturally, it is a notebook itself.
Other notebooks need access to nbinclude
in order to use it. Since it's a notebook in itself, the following shim is required to import it:
In [1]:
# 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)
Adding this shim to your notebook file will enable the behavior below
Notebooks can now be imported as if they were Python modules, for example:
In [2]:
import nbinclude as nbi
Importing normally reads all code cells in the notebook file.
One way to protect against this is the standard guard:
In [ ]:
if __name__ == "__main__":
print "This code will not run if the notebook is imported via the import statement
The other is to use the #NBIMPORT_STOP
macro (exact spelling - no space after the #
).
Everything in the notebook that is after this macro will not be run when the notebook is imported using the import statement
C-style includes for notebooks are also supported:
In [ ]:
# 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")
In [ ]:
# Omitting the ".ipynb" works, too
nbinclude("nbinclude")
In [ ]:
# So do absolute paths
nbinclude("/home/nikita/dev/ipython-notebooks/nbtools/nbinclude.ipynb")
In [ ]:
# And absolute paths that omit the ".ipynb"
nbinclude("/home/nikita/dev/ipython-notebooks/nbtools/nbinclude")
The classic guard works here, too:
In [ ]:
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)
#NBINCLUDE_STOP
and NBIMPORT_STOP
are distinct macros on purpose.
In [12]:
%%file nbinclude2.py
# See below the first header for documentation
# The code until then is bootstrap. It relies on an excessive number of hacks
# Do not allow the remainder of this file to be imported using the "import" statement
# The bootstrap process is designed for nbinclude instead of the import statement
#NBIMPORT_STOP
# This first cell is the only one run using the three-line nbinclude shim
with open("nbinclude.ipynb") as nbinclude_f:
import IPython.nbformat.current
try:
nbinclude
except NameError:
# Define nbinclude, if it is not already defined
# Uses the variable "nbinclude_f" to get the path to "nbinclude.ipynb", so it can
# be added to the module search path
# nbinclude_f = open("nbinclude.ipynb")
print nbinclude_f.name
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"
# Hacky notebook-finder. TODO: replace with the less hacky version below
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
# Now that nbinclude is available, we can run the remainder of this notebook until NBINCLUDE_STOP
nbinclude("nbinclude")
In [ ]: