Skip to content

Instantly share code, notes, and snippets.

@robclewley
Created April 15, 2015 15:54
Show Gist options
  • Save robclewley/75b7719119892b99d73b to your computer and use it in GitHub Desktop.
Save robclewley/75b7719119892b99d73b to your computer and use it in GitHub Desktop.
Module to import from ipython notebooks

Module to import from ipython notebooks

Origin

This module is entirely the work of Adrian Price-Whelan, and was directly collated from his notebook http://nbviewer.ipython.org/github/adrn/ipython/blob/1.x/examples/notebooks/Importing%20Notebooks.ipynb

Usage

Place this module in a location on your python path, then add a config instruction to your .ipython/profile_default/ipython_notebook_config.py:

c.InteractiveShellApp.exec_lines = [ 'import notebook_importing' ]

You will then be able to import directly from other ipython notebooks in every notebook session.

"""
Module directly collated from
http://nbviewer.ipython.org/github/adrn/ipython/blob/1.x/examples/notebooks/Importing%20Notebooks.ipynb
"""
import io, os, sys, types
from IPython.nbformat import current
from IPython.core.interactiveshell import InteractiveShell
def find_notebook(fullname, path=None):
"""find a notebook, given its fully qualified name and an optional path
This turns "foo.bar" into "foo/bar.ipynb"
and tries turning "Foo_Bar" into "Foo Bar" if Foo_Bar
does not exist.
"""
name = fullname.rsplit('.', 1)[-1]
if not path:
path = ['']
for d in path:
nb_path = os.path.join(d, name + ".ipynb")
if os.path.isfile(nb_path):
return nb_path
# let import Notebook_Name find "Notebook Name.ipynb"
nb_path = nb_path.replace("_", " ")
if os.path.isfile(nb_path):
return nb_path
class NotebookLoader(object):
"""Module Loader for IPython Notebooks"""
def __init__(self, path=None):
self.shell = InteractiveShell.instance()
self.path = path
def load_module(self, fullname):
"""import a notebook as a module"""
path = find_notebook(fullname, self.path)
print ("importing IPython notebook from %s" % path)
# load the notebook object
with io.open(path, 'r', encoding='utf-8') as f:
nb = current.read(f, 'json')
# create the module and add it to sys.modules
# if name in sys.modules:
# return sys.modules[name]
mod = types.ModuleType(fullname)
mod.__file__ = path
mod.__loader__ = self
sys.modules[fullname] = mod
# extra work to ensure that magics that would affect the user_ns
# actually affect the notebook module's ns
save_user_ns = self.shell.user_ns
self.shell.user_ns = mod.__dict__
try:
for cell in nb.worksheets[0].cells:
if cell.cell_type == 'code' and cell.language == 'python':
# transform the input to executable Python
code = self.shell.input_transformer_manager.transform_cell(cell.input)
# run the code in themodule
exec code in mod.__dict__
finally:
self.shell.user_ns = save_user_ns
return mod
class NotebookFinder(object):
"""Module finder that locates IPython Notebooks"""
def __init__(self):
self.loaders = {}
def find_module(self, fullname, path=None):
nb_path = find_notebook(fullname, path)
if not nb_path:
return
key = path
if path:
# lists aren't hashable
key = os.path.sep.join(path)
if key not in self.loaders:
self.loaders[key] = NotebookLoader(path)
return self.loaders[key]
# --------------
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
from IPython.display import display, HTML
formatter = HtmlFormatter()
lexer = PythonLexer()
# publish the CSS for pygments highlighting
display(HTML("""
<style type='text/css'>
%s
</style>
""" % formatter.get_style_defs()
))
def show_notebook(fname):
"""display a short summary of the cells of a notebook"""
with io.open(fname, 'r', encoding='utf-8') as f:
nb = current.read(f, 'json')
html = []
for cell in nb.worksheets[0].cells:
html.append("<h4>%s cell</h4>" % cell.cell_type)
if cell.cell_type == 'code':
html.append(highlight(cell.input, lexer, formatter))
else:
html.append("<pre>%s</pre>" % cell.source)
display(HTML('\n'.join(html)))
# Example
#show_notebook(os.path.join("nbimp", "mynotebook.ipynb"))
sys.meta_path.append(NotebookFinder())
@dxcapriccio
Copy link

Hi, thanks! it doesn't work well for me but i guess it is about the config file location. Currently I am using jupyter notebook and there are two config files under .jupyter and .ipython respectively. I wonder which config file i need to change? thank you!

@thejohnhoffer
Copy link

Thanks - this is awesome. I really was not looking forward to getting this to work until someone else has done it.

@thejohnhoffer
Copy link

This has been super helpful as a starting point for a little extension I made to read an ipynb cell-by-cell into a jupyter-console. I'm hoping to build it up a bit to also write from the jupyter-console to a specific ipynb cell.

I'm just letting you know I'm using "your" code, and I'm also happy it led me to discover your PyDSTools. Cheers, @robclewley.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment