Importing Notebooks.ipynb
763 lines
| 21.7 KiB
| text/plain
|
TextLexer
MinRK
|
r11699 | { | ||
Min RK
|
r18669 | "cells": [ | ||
MinRK
|
r11699 | { | ||
Min RK
|
r18669 | "cell_type": "markdown", | ||
"metadata": {}, | ||||
"source": [ | ||||
"# Importing IPython Notebooks as Modules" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"It is a common problem that people want to import code from IPython Notebooks.\n", | ||||
"This is made difficult by the fact that Notebooks are not plain Python files,\n", | ||||
"and thus cannot be imported by the regular Python machinery.\n", | ||||
"\n", | ||||
"Fortunately, Python provides some fairly sophisticated [hooks](http://www.python.org/dev/peps/pep-0302/) into the import machinery,\n", | ||||
"so we can actually make IPython notebooks importable without much difficulty,\n", | ||||
"and only using public APIs." | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 1, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
"outputs": [], | ||||
"source": [ | ||||
"import io, os, sys, types" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 2, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
"outputs": [], | ||||
"source": [ | ||||
Min RK
|
r21638 | "import nbformat\n", | ||
"\n", | ||||
Pietro Battiston
|
r21008 | "from IPython import get_ipython\n", | ||
Min RK
|
r18669 | "from IPython.core.interactiveshell import InteractiveShell" | ||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"Import hooks typically take the form of two objects:\n", | ||||
"\n", | ||||
"1. a Module **Loader**, which takes a module name (e.g. `'IPython.display'`), and returns a Module\n", | ||||
"2. a Module **Finder**, which figures out whether a module might exist, and tells Python what **Loader** to use" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 3, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
"outputs": [], | ||||
"source": [ | ||||
"def find_notebook(fullname, path=None):\n", | ||||
" \"\"\"find a notebook, given its fully qualified name and an optional path\n", | ||||
" \n", | ||||
" This turns \"foo.bar\" into \"foo/bar.ipynb\"\n", | ||||
" and tries turning \"Foo_Bar\" into \"Foo Bar\" if Foo_Bar\n", | ||||
" does not exist.\n", | ||||
" \"\"\"\n", | ||||
" name = fullname.rsplit('.', 1)[-1]\n", | ||||
" if not path:\n", | ||||
" path = ['']\n", | ||||
" for d in path:\n", | ||||
" nb_path = os.path.join(d, name + \".ipynb\")\n", | ||||
" if os.path.isfile(nb_path):\n", | ||||
" return nb_path\n", | ||||
" # let import Notebook_Name find \"Notebook Name.ipynb\"\n", | ||||
" nb_path = nb_path.replace(\"_\", \" \")\n", | ||||
" if os.path.isfile(nb_path):\n", | ||||
" return nb_path\n", | ||||
" " | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"## Notebook Loader" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"Here we have our Notebook Loader.\n", | ||||
"It's actually quite simple - once we figure out the filename of the module,\n", | ||||
"all it does is:\n", | ||||
"\n", | ||||
"1. load the notebook document into memory\n", | ||||
"2. create an empty Module\n", | ||||
"3. execute every cell in the Module namespace\n", | ||||
"\n", | ||||
"Since IPython cells can have extended syntax,\n", | ||||
"the IPython transform is applied to turn each of these cells into their pure-Python counterparts before executing them.\n", | ||||
"If all of your notebook cells are pure-Python,\n", | ||||
"this step is unnecessary." | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 4, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
"outputs": [], | ||||
"source": [ | ||||
"class NotebookLoader(object):\n", | ||||
" \"\"\"Module Loader for IPython Notebooks\"\"\"\n", | ||||
" def __init__(self, path=None):\n", | ||||
" self.shell = InteractiveShell.instance()\n", | ||||
" self.path = path\n", | ||||
" \n", | ||||
" def load_module(self, fullname):\n", | ||||
" \"\"\"import a notebook as a module\"\"\"\n", | ||||
" path = find_notebook(fullname, self.path)\n", | ||||
" \n", | ||||
Min RK
|
r21638 | " print (\"importing notebook from %s\" % path)\n", | ||
Min RK
|
r18669 | " \n", | ||
" # load the notebook object\n", | ||||
Min RK
|
r21638 | " nb = nbformat.read(path, as_version=4)\n", | ||
Min RK
|
r18669 | " \n", | ||
" \n", | ||||
" # create the module and add it to sys.modules\n", | ||||
" # if name in sys.modules:\n", | ||||
" # return sys.modules[name]\n", | ||||
" mod = types.ModuleType(fullname)\n", | ||||
" mod.__file__ = path\n", | ||||
" mod.__loader__ = self\n", | ||||
Pietro Battiston
|
r21008 | " mod.__dict__['get_ipython'] = get_ipython\n", | ||
Min RK
|
r18669 | " sys.modules[fullname] = mod\n", | ||
" \n", | ||||
" # extra work to ensure that magics that would affect the user_ns\n", | ||||
" # actually affect the notebook module's ns\n", | ||||
" save_user_ns = self.shell.user_ns\n", | ||||
" self.shell.user_ns = mod.__dict__\n", | ||||
" \n", | ||||
" try:\n", | ||||
Min RK
|
r21638 | " for cell in nb.cells:\n", | ||
" if cell.cell_type == 'code':\n", | ||||
Min RK
|
r18669 | " # transform the input to executable Python\n", | ||
Min RK
|
r21638 | " code = self.shell.input_transformer_manager.transform_cell(cell.source)\n", | ||
Min RK
|
r18669 | " # run the code in themodule\n", | ||
" exec(code, mod.__dict__)\n", | ||||
" finally:\n", | ||||
" self.shell.user_ns = save_user_ns\n", | ||||
" return mod\n" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"## The Module Finder" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"The finder is a simple object that tells you whether a name can be imported,\n", | ||||
"and returns the appropriate loader.\n", | ||||
"All this one does is check, when you do:\n", | ||||
"\n", | ||||
"```python\n", | ||||
"import mynotebook\n", | ||||
"```\n", | ||||
"\n", | ||||
"it checks whether `mynotebook.ipynb` exists.\n", | ||||
"If a notebook is found, then it returns a NotebookLoader.\n", | ||||
"\n", | ||||
"Any extra logic is just for resolving paths within packages." | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 5, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
"outputs": [], | ||||
"source": [ | ||||
"class NotebookFinder(object):\n", | ||||
" \"\"\"Module finder that locates IPython Notebooks\"\"\"\n", | ||||
" def __init__(self):\n", | ||||
" self.loaders = {}\n", | ||||
" \n", | ||||
" def find_module(self, fullname, path=None):\n", | ||||
" nb_path = find_notebook(fullname, path)\n", | ||||
" if not nb_path:\n", | ||||
" return\n", | ||||
" \n", | ||||
" key = path\n", | ||||
" if path:\n", | ||||
" # lists aren't hashable\n", | ||||
" key = os.path.sep.join(path)\n", | ||||
" \n", | ||||
" if key not in self.loaders:\n", | ||||
" self.loaders[key] = NotebookLoader(path)\n", | ||||
" return self.loaders[key]\n" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"## Register the hook" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"Now we register the `NotebookFinder` with `sys.meta_path`" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 6, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
"outputs": [], | ||||
"source": [ | ||||
"sys.meta_path.append(NotebookFinder())" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"After this point, my notebooks should be importable.\n", | ||||
"\n", | ||||
"Let's look at what we have in the CWD:" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 7, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"name": "stdout", | ||||
"output_type": "stream", | ||||
"text": [ | ||||
"__init__.py \u001b[34m__pycache__\u001b[m\u001b[m/ mynotebook.ipynb \u001b[34mnbs\u001b[m\u001b[m/\r\n" | ||||
] | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"ls nbpackage" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"So I should be able to `import nbimp.mynotebook`.\n" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"### Aside: displaying notebooks" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"Here is some simple code to display the contents of a notebook\n", | ||||
"with syntax highlighting, etc." | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 8, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"data": { | ||||
"text/html": [ | ||||
"\n", | ||||
"<style type='text/css'>\n", | ||||
".hll { background-color: #ffffcc }\n", | ||||
".c { color: #408080; font-style: italic } /* Comment */\n", | ||||
".err { border: 1px solid #FF0000 } /* Error */\n", | ||||
".k { color: #008000; font-weight: bold } /* Keyword */\n", | ||||
".o { color: #666666 } /* Operator */\n", | ||||
".cm { color: #408080; font-style: italic } /* Comment.Multiline */\n", | ||||
".cp { color: #BC7A00 } /* Comment.Preproc */\n", | ||||
".c1 { color: #408080; font-style: italic } /* Comment.Single */\n", | ||||
".cs { color: #408080; font-style: italic } /* Comment.Special */\n", | ||||
".gd { color: #A00000 } /* Generic.Deleted */\n", | ||||
".ge { font-style: italic } /* Generic.Emph */\n", | ||||
".gr { color: #FF0000 } /* Generic.Error */\n", | ||||
".gh { color: #000080; font-weight: bold } /* Generic.Heading */\n", | ||||
".gi { color: #00A000 } /* Generic.Inserted */\n", | ||||
".go { color: #888888 } /* Generic.Output */\n", | ||||
".gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n", | ||||
".gs { font-weight: bold } /* Generic.Strong */\n", | ||||
".gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n", | ||||
".gt { color: #0044DD } /* Generic.Traceback */\n", | ||||
".kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n", | ||||
".kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n", | ||||
".kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n", | ||||
".kp { color: #008000 } /* Keyword.Pseudo */\n", | ||||
".kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n", | ||||
".kt { color: #B00040 } /* Keyword.Type */\n", | ||||
".m { color: #666666 } /* Literal.Number */\n", | ||||
".s { color: #BA2121 } /* Literal.String */\n", | ||||
".na { color: #7D9029 } /* Name.Attribute */\n", | ||||
".nb { color: #008000 } /* Name.Builtin */\n", | ||||
".nc { color: #0000FF; font-weight: bold } /* Name.Class */\n", | ||||
".no { color: #880000 } /* Name.Constant */\n", | ||||
".nd { color: #AA22FF } /* Name.Decorator */\n", | ||||
".ni { color: #999999; font-weight: bold } /* Name.Entity */\n", | ||||
".ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n", | ||||
".nf { color: #0000FF } /* Name.Function */\n", | ||||
".nl { color: #A0A000 } /* Name.Label */\n", | ||||
".nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n", | ||||
".nt { color: #008000; font-weight: bold } /* Name.Tag */\n", | ||||
".nv { color: #19177C } /* Name.Variable */\n", | ||||
".ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n", | ||||
".w { color: #bbbbbb } /* Text.Whitespace */\n", | ||||
".mb { color: #666666 } /* Literal.Number.Bin */\n", | ||||
".mf { color: #666666 } /* Literal.Number.Float */\n", | ||||
".mh { color: #666666 } /* Literal.Number.Hex */\n", | ||||
".mi { color: #666666 } /* Literal.Number.Integer */\n", | ||||
".mo { color: #666666 } /* Literal.Number.Oct */\n", | ||||
".sb { color: #BA2121 } /* Literal.String.Backtick */\n", | ||||
".sc { color: #BA2121 } /* Literal.String.Char */\n", | ||||
".sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n", | ||||
".s2 { color: #BA2121 } /* Literal.String.Double */\n", | ||||
".se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n", | ||||
".sh { color: #BA2121 } /* Literal.String.Heredoc */\n", | ||||
".si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n", | ||||
".sx { color: #008000 } /* Literal.String.Other */\n", | ||||
".sr { color: #BB6688 } /* Literal.String.Regex */\n", | ||||
".s1 { color: #BA2121 } /* Literal.String.Single */\n", | ||||
".ss { color: #19177C } /* Literal.String.Symbol */\n", | ||||
".bp { color: #008000 } /* Name.Builtin.Pseudo */\n", | ||||
".vc { color: #19177C } /* Name.Variable.Class */\n", | ||||
".vg { color: #19177C } /* Name.Variable.Global */\n", | ||||
".vi { color: #19177C } /* Name.Variable.Instance */\n", | ||||
".il { color: #666666 } /* Literal.Number.Integer.Long */\n", | ||||
"</style>\n" | ||||
], | ||||
"text/plain": [ | ||||
"<IPython.core.display.HTML object>" | ||||
] | ||||
}, | ||||
"metadata": {}, | ||||
"output_type": "display_data" | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"from pygments import highlight\n", | ||||
"from pygments.lexers import PythonLexer\n", | ||||
"from pygments.formatters import HtmlFormatter\n", | ||||
"\n", | ||||
"from IPython.display import display, HTML\n", | ||||
"\n", | ||||
"formatter = HtmlFormatter()\n", | ||||
"lexer = PythonLexer()\n", | ||||
"\n", | ||||
"# publish the CSS for pygments highlighting\n", | ||||
"display(HTML(\"\"\"\n", | ||||
"<style type='text/css'>\n", | ||||
"%s\n", | ||||
"</style>\n", | ||||
"\"\"\" % formatter.get_style_defs()\n", | ||||
"))" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 9, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"data": { | ||||
"text/html": [ | ||||
"<h4>markdown cell</h4>\n", | ||||
"<pre># My Notebook</pre>\n", | ||||
"<h4>code cell</h4>\n", | ||||
"<div class=\"highlight\"><pre><span class=\"k\">def</span> <span class=\"nf\">foo</span><span class=\"p\">():</span>\n", | ||||
" <span class=\"k\">return</span> <span class=\"s\">"foo"</span>\n", | ||||
"</pre></div>\n", | ||||
"\n", | ||||
"<h4>code cell</h4>\n", | ||||
"<div class=\"highlight\"><pre><span class=\"k\">def</span> <span class=\"nf\">has_ip_syntax</span><span class=\"p\">():</span>\n", | ||||
" <span class=\"n\">listing</span> <span class=\"o\">=</span> <span class=\"err\">!</span><span class=\"n\">ls</span>\n", | ||||
" <span class=\"k\">return</span> <span class=\"n\">listing</span>\n", | ||||
"</pre></div>\n", | ||||
"\n", | ||||
"<h4>code cell</h4>\n", | ||||
"<div class=\"highlight\"><pre><span class=\"k\">def</span> <span class=\"nf\">whatsmyname</span><span class=\"p\">():</span>\n", | ||||
" <span class=\"k\">return</span> <span class=\"n\">__name__</span>\n", | ||||
"</pre></div>\n" | ||||
], | ||||
"text/plain": [ | ||||
"<IPython.core.display.HTML object>" | ||||
] | ||||
}, | ||||
"metadata": {}, | ||||
"output_type": "display_data" | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"def show_notebook(fname):\n", | ||||
" \"\"\"display a short summary of the cells of a notebook\"\"\"\n", | ||||
Min RK
|
r21638 | " nb = nbformat.read(fname, as_version=4)\n", | ||
Min RK
|
r18669 | " html = []\n", | ||
Min RK
|
r21638 | " for cell in nb.cells:\n", | ||
Min RK
|
r18669 | " html.append(\"<h4>%s cell</h4>\" % cell.cell_type)\n", | ||
" if cell.cell_type == 'code':\n", | ||||
Min RK
|
r21638 | " html.append(highlight(cell.source, lexer, formatter))\n", | ||
Min RK
|
r18669 | " else:\n", | ||
" html.append(\"<pre>%s</pre>\" % cell.source)\n", | ||||
" display(HTML('\\n'.join(html)))\n", | ||||
"\n", | ||||
"show_notebook(os.path.join(\"nbpackage\", \"mynotebook.ipynb\"))" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"So my notebook has a heading cell and some code cells,\n", | ||||
"one of which contains some IPython syntax.\n", | ||||
"\n", | ||||
"Let's see what happens when we import it" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 10, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"name": "stdout", | ||||
"output_type": "stream", | ||||
"text": [ | ||||
"importing notebook from /Users/minrk/dev/ip/mine/examples/IPython Kernel/nbpackage/mynotebook.ipynb\n" | ||||
] | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"from nbpackage import mynotebook" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"Hooray, it imported! Does it work?" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 11, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"data": { | ||||
"text/plain": [ | ||||
"'foo'" | ||||
] | ||||
}, | ||||
"execution_count": 11, | ||||
"metadata": {}, | ||||
"output_type": "execute_result" | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"mynotebook.foo()" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"Hooray again!\n", | ||||
"\n", | ||||
"Even the function that contains IPython syntax works:" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 12, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"data": { | ||||
"text/plain": [ | ||||
"['Animations Using clear_output.ipynb',\n", | ||||
" 'Background Jobs.ipynb',\n", | ||||
" 'Beyond Plain Python.ipynb',\n", | ||||
" 'Capturing Output.ipynb',\n", | ||||
" 'Cell Magics.ipynb',\n", | ||||
" 'Custom Display Logic.ipynb',\n", | ||||
" 'Importing Notebooks.ipynb',\n", | ||||
" 'Index.ipynb',\n", | ||||
" 'Plotting in the Notebook.ipynb',\n", | ||||
" 'Raw Input in the Notebook.ipynb',\n", | ||||
" 'Rich Output.ipynb',\n", | ||||
" 'Script Magics.ipynb',\n", | ||||
" 'SymPy.ipynb',\n", | ||||
" 'Terminal Usage.ipynb',\n", | ||||
" 'Third Party Rich Output.ipynb',\n", | ||||
" 'Trapezoid Rule.ipynb',\n", | ||||
" 'Working With External Code.ipynb',\n", | ||||
" '__pycache__',\n", | ||||
" 'data',\n", | ||||
" 'example-demo.py',\n", | ||||
" 'gui',\n", | ||||
" 'ipython-completion.bash',\n", | ||||
" 'ipython-get-history.py',\n", | ||||
" 'ipython.desktop',\n", | ||||
" 'nbpackage']" | ||||
] | ||||
}, | ||||
"execution_count": 12, | ||||
"metadata": {}, | ||||
"output_type": "execute_result" | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"mynotebook.has_ip_syntax()" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"## Notebooks in packages" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"We also have a notebook inside the `nb` package,\n", | ||||
"so let's make sure that works as well." | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 13, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"name": "stdout", | ||||
"output_type": "stream", | ||||
"text": [ | ||||
"__init__.py \u001b[34m__pycache__\u001b[m\u001b[m/ other.ipynb\r\n" | ||||
] | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"ls nbpackage/nbs" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"Note that the `__init__.py` is necessary for `nb` to be considered a package,\n", | ||||
"just like usual." | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 14, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"data": { | ||||
"text/html": [ | ||||
"<h4>markdown cell</h4>\n", | ||||
"<pre>This notebook just defines `bar`</pre>\n", | ||||
"<h4>code cell</h4>\n", | ||||
"<div class=\"highlight\"><pre><span class=\"k\">def</span> <span class=\"nf\">bar</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">):</span>\n", | ||||
" <span class=\"k\">return</span> <span class=\"s\">"bar"</span> <span class=\"o\">*</span> <span class=\"n\">x</span>\n", | ||||
"</pre></div>\n" | ||||
], | ||||
"text/plain": [ | ||||
"<IPython.core.display.HTML object>" | ||||
] | ||||
}, | ||||
"metadata": {}, | ||||
"output_type": "display_data" | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"show_notebook(os.path.join(\"nbpackage\", \"nbs\", \"other.ipynb\"))" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 15, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"name": "stdout", | ||||
"output_type": "stream", | ||||
"text": [ | ||||
"importing notebook from /Users/minrk/dev/ip/mine/examples/IPython Kernel/nbpackage/nbs/other.ipynb\n" | ||||
] | ||||
}, | ||||
{ | ||||
"data": { | ||||
"text/plain": [ | ||||
"'barbarbarbarbar'" | ||||
] | ||||
}, | ||||
"execution_count": 15, | ||||
"metadata": {}, | ||||
"output_type": "execute_result" | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"from nbpackage.nbs import other\n", | ||||
"other.bar(5)" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"So now we have importable notebooks, from both the local directory and inside packages.\n", | ||||
"\n", | ||||
"I can even put a notebook inside IPython, to further demonstrate that this is working properly:" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 16, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"data": { | ||||
"text/plain": [ | ||||
"'/Users/minrk/dev/ip/mine/IPython/utils/inside_ipython.ipynb'" | ||||
] | ||||
}, | ||||
"execution_count": 16, | ||||
"metadata": {}, | ||||
"output_type": "execute_result" | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"import shutil\n", | ||||
Min RK
|
r21638 | "from IPython.paths import get_ipython_package_dir\n", | ||
Min RK
|
r18669 | "\n", | ||
"utils = os.path.join(get_ipython_package_dir(), 'utils')\n", | ||||
"shutil.copy(os.path.join(\"nbpackage\", \"mynotebook.ipynb\"),\n", | ||||
" os.path.join(utils, \"inside_ipython.ipynb\")\n", | ||||
")" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"and import the notebook from `IPython.utils`" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Min RK
|
r21638 | "execution_count": 17, | ||
Min RK
|
r18669 | "metadata": { | ||
"collapsed": false | ||||
}, | ||||
Min RK
|
r21638 | "outputs": [ | ||
{ | ||||
"name": "stdout", | ||||
"output_type": "stream", | ||||
"text": [ | ||||
"importing notebook from /Users/minrk/dev/ip/mine/IPython/utils/inside_ipython.ipynb\n" | ||||
] | ||||
}, | ||||
{ | ||||
"data": { | ||||
"text/plain": [ | ||||
"'IPython.utils.inside_ipython'" | ||||
] | ||||
}, | ||||
"execution_count": 17, | ||||
"metadata": {}, | ||||
"output_type": "execute_result" | ||||
} | ||||
], | ||||
Min RK
|
r18669 | "source": [ | ||
"from IPython.utils import inside_ipython\n", | ||||
"inside_ipython.whatsmyname()" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"This approach can even import functions and classes that are defined in a notebook using the `%%cython` magic." | ||||
] | ||||
MinRK
|
r11699 | } | ||
Min RK
|
r18669 | ], | ||
"metadata": { | ||||
"gist_id": "6011986", | ||||
Min RK
|
r20278 | "kernelspec": { | ||
"display_name": "Python 3", | ||||
"language": "python", | ||||
"name": "python3" | ||||
}, | ||||
"language_info": { | ||||
"codemirror_mode": { | ||||
"name": "ipython", | ||||
"version": 3 | ||||
}, | ||||
"file_extension": ".py", | ||||
"mimetype": "text/x-python", | ||||
"name": "python", | ||||
"nbconvert_exporter": "python", | ||||
"pygments_lexer": "ipython3", | ||||
Jonathan Frederic
|
r20536 | "version": "3.4.3" | ||
Min RK
|
r20278 | } | ||
Min RK
|
r18669 | }, | ||
"nbformat": 4, | ||||
"nbformat_minor": 0 | ||||
Min RK
|
r20278 | } | ||