Skip to content

Instantly share code, notes, and snippets.

@jbwhit
Last active September 21, 2023 04:50
Show Gist options
  • Star 34 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save jbwhit/881bdeeaae3e4128947c to your computer and use it in GitHub Desktop.
Save jbwhit/881bdeeaae3e4128947c to your computer and use it in GitHub Desktop.
Saves Jupyter Notebooks as .py and .html files automatically. Add to the ipython_notebook_config.py file of your associated profile.
import os
from subprocess import check_call
def post_save(model, os_path, contents_manager):
"""post-save hook for converting notebooks to .py and .html files."""
if model['type'] != 'notebook':
return # only do this for notebooks
d, fname = os.path.split(os_path)
check_call(['jupyter', 'nbconvert', '--to', 'script', fname], cwd=d)
check_call(['jupyter', 'nbconvert', '--to', 'html', fname], cwd=d)
c.FileContentsManager.post_save_hook = post_save
@naoko
Copy link

naoko commented Nov 22, 2016

This works great! Thank you. I got depreciate warning on jupyter version 4.2.0 so I changed from 'ipython' to 'jupyter' as follows.

check_call(['jupyter', 'nbconvert', '--to', 'script', fname], cwd=d)
check_call(['jupyter', 'nbconvert', '--to', 'html', fname], cwd=d)

@812624
Copy link

812624 commented Dec 25, 2017

What exactly that 'c' refers to, in line : c.FileContentsManager.post_save_hook = post_save

@edwardtilley
Copy link

edwardtilley commented Nov 21, 2019

Great addition. Thanks for sharing this... the video is a couple of years old, so is there an update?

FYI - For AnaConda users, I show this ipython_notebook_config.py config file in two paths:

  1. ..\Anaconda3\envs<env>\Lib\site-packages\jupyter_core\tests\dotipython\profile_default
    It contains just:
    c.NotebookApp.open_browser = False

  2. ..\Anaconda3\envs<env>\Lib\site-packages\jupyter_core\tests\dotipython_empty\profile_default
    This file contains pages of commented options - and ...

Python callable or importstring thereof

To be called on a contents model prior to save.

This can be used to process the structure, such as removing notebook outputs

or other side effects that should not be saved.

It will be called as (all arguments passed by keyword)::

hook(path=path, model=model, contents_manager=self)

Or ...

to be called on the path of a file just saved.

This can be used to process the file on disk, such as converting the notebook

to a script or HTML via nbconvert.

It will be called as (all arguments passed by keyword)::

hook(os_path=os_path, model=model, contents_manager=instance)

- path: the filesystem path to the file just written - model: the model

representing the file - contents_manager: this ContentsManager instance

c.FileContentsManager.post_save_hook = None

DEPRECATED, use post_save_hook

c.FileContentsManager.save_script = False

Any advice here? It looks like your script belongs here in the second config file.

@jbwhit
Copy link
Author

jbwhit commented Jan 20, 2020

So it looks like this stackoverflow answer has the right way to go about this: https://stackoverflow.com/questions/29329667/ipython-notebook-script-deprecated-how-to-replace-with-post-save-hook

jupyter notebook --generate-config

and it will output the file name:

Writing default config to: /Users/user/.jupyter/jupyter_notebook_config.py

And that's the location that you'd like to edit. I've also tweaked the call to use jupyter instead of ipython.

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