Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ipython notebook --script deprecated. How to replace with post save hook?

I have been using "ipython --script" to automatically save a .py file for each ipython notebook so I can use it to import classes into other notebooks. But this recenty stopped working, and I get the following error message:

`--script` is deprecated. You can trigger nbconvert via pre- or post-save hooks:
ContentsManager.pre_save_hook
FileContentsManager.post_save_hook
A post-save hook has been registered that calls:
ipython nbconvert --to script [notebook]
which behaves similarly to `--script`.

As I understand this I need to set up a post-save hook, but I do not understand how to do this. Can someone explain?

like image 831
Louic Avatar asked Mar 29 '15 13:03

Louic


People also ask

How do you replace a notebook in Python?

The new Find and Replace dialog is found under the Edit menu of the notebook. If you're in command mode, you can press the F key to bring up the dialog. The dialog displays a live preview of the find and replace action you specify.

How do I change the save directory in Jupyter Notebook?

Change Jupyter Notebook startup folder (Windows) Copy the Jupyter Notebook launcher from the menu to the desktop. Right click on the new launcher and change the Target field, change %USERPROFILE% to the full path of the folder which will contain all the notebooks.

How do you save in IPython notebook?

Saving your edits is simple. There is a disk icon in the upper left of the Jupyter tool bar. Click the save icon and your notebook edits are saved. It's important to realize that you will only be saving edits you've made to the text sections and to the coding windows.

Is IPython deprecated?

The IPython console is now deprecated and if you want to start it, you'll need to use the Jupyter Console, which is a terminal-based console frontend for Jupyter kernels.


2 Answers

[UPDATED per comment by @mobius dumpling]

Find your config files:

Jupyter / ipython >= 4.0

jupyter --config-dir

ipython <4.0

ipython locate profile default

If you need a new config:

Jupyter / ipython >= 4.0

jupyter notebook --generate-config

ipython <4.0

ipython profile create

Within this directory, there will be a file called [jupyter | ipython]_notebook_config.py, put the following code from ipython's GitHub issues page in that file:

import os
from subprocess import check_call

c = get_config()

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['ipython', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

For Jupyter, replace ipython with jupyter in check_call.

Note that there's a corresponding 'pre-save' hook, and also that you can call any subprocess or run any arbitrary code there...if you want to do any thing fancy like checking some condition first, notifying API consumers, or adding a git commit for the saved script.

Cheers,

-t.

like image 187
Tristan Reid Avatar answered Oct 22 '22 00:10

Tristan Reid


Here is another approach that doesn't invoke a new thread (with check_call). Add the following to jupyter_notebook_config.py as in Tristan's answer:

import io
import os
from notebook.utils import to_api_path

_script_exporter = None

def script_post_save(model, os_path, contents_manager, **kwargs):
    """convert notebooks to Python script after save with nbconvert

    replaces `ipython notebook --script`
    """
    from nbconvert.exporters.script import ScriptExporter

    if model['type'] != 'notebook':
        return

    global _script_exporter
    if _script_exporter is None:
        _script_exporter = ScriptExporter(parent=contents_manager)
    log = contents_manager.log

    base, ext = os.path.splitext(os_path)
    py_fname = base + '.py'
    script, resources = _script_exporter.from_filename(os_path)
    script_fname = base + resources.get('output_extension', '.txt')
    log.info("Saving script /%s", to_api_path(script_fname, contents_manager.root_dir))
    with io.open(script_fname, 'w', encoding='utf-8') as f:
        f.write(script)

c.FileContentsManager.post_save_hook = script_post_save

Disclaimer: I'm pretty sure I got this from SO somwhere, but can't find it now. Putting it here so it's easier to find in future (:

like image 38
drevicko Avatar answered Oct 21 '22 23:10

drevicko