Skip to content Skip to sidebar Skip to footer

How Can I Import One Jupyter Notebook Into Another

Apparently it's possible to import one Jupyter notebook into another. The linked page has quite a bit of code to do it. Am I supposed to add that code to the importing notebook? T

Solution 1:

Yes, you can add all of that code to a notebook if you want.

And yes, you shouldn't do so as a general solution.

A notebook is a complicated structure, as alluded to in the details of the text (I think it's JSON). It can contain python code, it can contain magics - cython, bash, latex and more - which would not be understood by the Python kernel. Essentially you have to replicate a portion of the functionality of the normal Python import process, as natively Python won't understand there is Python code inside an Ipython notebook.

However ... normally if you have a significant amount of Python code you would split it into modules, and then import the modules. These work as normal, because it is a normal Python import.

For example, once the code has been loaded to tell it how to understand what a notebook is, the actual import is only

import nbpackage.mynotebook

We can use the same technique with the module import code - find_notebook and NotebookLoader can be put into a helper module (e.g. helper.py), and all you would have to do is, from within your notebook, use from helper import NotebookFinder.

I suspect you'd still have to call sys.meta_path.append(NotebookFinder()) from inside your notebook along with the import.

Here is a specific example of how you can use the import capabilities to create an API drawn from a notebook:

Create a notebook. We'll call it scanner.ipynb:

import os, sys
defscanner(start):
    for root, dirs,files in os.walk(start):
        # remove any already processed fileif'done'in dirs:
            dirs.remove('done')
        for names in files:
            name, ext = os.path.splitext(names)
            # only interested in media filesif ext == '.mp4'or ext == '.mkv':
                print(name)

Create a regular python file called reuse.py. This is your general re-usable Ipython import module:

#! /usr/env/bin python# *-* coding: utf-8 *-*import io, os, sys, types
from IPython import get_ipython
from nbformat import read
from IPython.core.interactiveshell import InteractiveShell

deffind_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]
    ifnot 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

classNotebookLoader(object):
    """Module Loader for Jupyter Notebooks"""def__init__(self, path=None):
        self.shell = InteractiveShell.instance()
        self.path = path

    defload_module(self, fullname):
        """import a notebook as a module"""
        path = find_notebook(fullname, self.path)

        print ("importing Jupyter notebook from %s" % path)

        # load the notebook objectwith io.open(path, 'r', encoding='utf-8') as f:
            nb = read(f, 4)


        # 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
        mod.__dict__['get_ipython'] = get_ipython
        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.cells:
            if cell.cell_type == 'code':
                # transform the input to executable Python
                code = self.shell.input_transformer_manager.transform_cell(cell.source)
                # run the code in themoduleexec(code, mod.__dict__)
        finally:
            self.shell.user_ns = save_user_ns
        return mod

classNotebookFinder(object):
    """Module finder that locates Jupyter Notebooks"""def__init__(self):
        self.loaders = {}

    deffind_module(self, fullname, path=None):
        nb_path = find_notebook(fullname, path)
        ifnot nb_path:
            return

        key = path
        if path:
            # lists aren't hashable
            key = os.path.sep.join(path)

        if key notin self.loaders:
            self.loaders[key] = NotebookLoader(path)
        return self.loaders[key]

Create your specific API file that connects the loader above with the notebook above. Call it scan_api.py:

# Note the python import hereimport reuse, sys

# This is the Ipython hook
sys.meta_path.append(reuse.NotebookFinder())
import scanner
# And now we can drawn upon the code
dir_to_scan = "/username/location"
scanner.scanner(dir_to_scan)

Solution 2:

Simple Solution with 2 lines of code

Use 'nbimporter' package in python for importing another notebook A (or its function) in notebook B. You can install 'nbimporter' by using the command - pip install nbimporter

Assume there are two Notebooks A.ipynb and B.ipynb. we are trying to import Notebook A (or its function) inside B Code sample below should solve the issue.

Inside Notebook B.ipynb

import nbimporter
import A  # or dothis --> from A import func1

Post a Comment for "How Can I Import One Jupyter Notebook Into Another"