Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement MinRK's notebook import code.
- Loading branch information
1 parent
3230498
commit 15e3e16
Showing
1 changed file
with
87 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
__author__ = 'agross' | ||
|
||
""" | ||
Code taken from MinRK's Gist. | ||
http://nbviewer.ipython.org/gist/minrk/6011986 | ||
""" | ||
|
||
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""" | ||
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 | ||
|
||
|
||
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] | ||
|
||
|
||
sys.meta_path.append(NotebookFinder()) |