24

I would like to leave an IPython notebook running to do some computation + show some visuals.

Once the IPython notebook has finished, I want the last cell in the IPython notebook to programmatically save the IPython notebook. Then I want to copy the notebook (with all output) to another directory to keep a record of results.

The copying bit I can code up easily, but I am not sure how to get an IPython notebook to programatically save itself? Is this possible? Thanks in advance!

applecider
  • 2,111
  • 4
  • 16
  • 34
  • 1
    Saving is done from the notebook web interface, which the kernel doesn't really know about. But you could make a cell that [displays Javascript](http://ipython.readthedocs.org/en/stable/api/generated/IPython.display.html#IPython.display.Javascript) to call the frontend save function. – Thomas K Aug 26 '15 at 23:54
  • 2
    With IPython < 4, you could do something like: `from IPython.display import display,Javascript display(Javascript('IPython.notebook.save_checkpoint();'))` – Taar Aug 28 '15 at 03:44
  • @Taar, thanks! That was the answer I was looking for; would accept as answer if it were answer! – applecider Aug 28 '15 at 04:35

2 Answers2

16

I am taking @Taar's comment and making it an actual answer since it worked for the original person who asked the question and for myself.

from IPython.display import display, Javascript
display(Javascript('IPython.notebook.save_checkpoint();'))

This will create checkpoints - same thing as CTRL-s.

Note: in Jupyter, CTRL-s triggers an async process and the file save is actually completed only a few seconds later. If you want a blocking save operation in a notebook, use this little function (file_path is the path to the notebook file):

import time
from IPython.display import display, Javascript
import hashlib

def save_notebook(file_path):
    start_md5 = hashlib.md5(open(file_path,'rb').read()).hexdigest()
    display(Javascript('IPython.notebook.save_checkpoint();'))
    current_md5 = start_md5
    
    while start_md5 == current_md5:
        time.sleep(1)
        current_md5 = hashlib.md5(open(file_path,'rb').read()).hexdigest()
Eric O Lebigot
  • 86,421
  • 44
  • 210
  • 254
Raphvanns
  • 1,469
  • 16
  • 20
  • If I am running this from the command line (on a remote server where I am not the user currently using the notebook) how do I specify which notebook I want saved? – zozo Jan 09 '20 at 03:33
  • @zozo, I have no ideas. Note: yours is an entirely different question since you are trying to save a notebook from outside, I suggest you open another new question. – Raphvanns Jan 10 '20 at 04:19
  • 3
    This won't work when using the JupyterLab interface, see [here](https://github.com/jupyterlab/jupyterlab/issues/7627). (Also I think the code should read `import time`, and not `from time import sleep`.) – Wayne Feb 14 '20 at 02:36
  • 1
    This unfortunately doesn't work with Jupyter Lab (3.2.5): I get `Javascript Error: IPython is not defined`. – Eric O Lebigot Dec 31 '21 at 14:20
4

The ipython magic command %notebook will help you here. It is shown on this page (search for %notebook).

To save your current notebook history to the file "foo.ipynb" just enter:

%notebook -e foo.ipynb

At the point you want it to happen

or1426
  • 879
  • 4
  • 7
  • 2
    Be aware that this saves your *history* as a new notebook. If you've run the notebook from start to finish without re-running any cells and run this at the end, that will be what you expect. If you re-run or re-order any cells, it may not do what you want. – Thomas K Aug 26 '15 at 23:50
  • or1426, thanks but for some reason I am not getting the output in foo.ipynb, is there any way to do that? – applecider Aug 27 '15 at 04:53
  • Is there a way to dynamically add the path to save as well? Eg `%notebook path_variable_from_runtime\name.ipynb` – CodeCollector Jan 03 '18 at 15:50
  • 1
    if `some_python_var` is a python variable with the path you want, you can `%notebook $some_python_var` – fonini Feb 27 '19 at 20:58