Save an IPython notebook programmatically from within itself?
Asked Answered
A

3

31

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!

Admissible answered 26/8, 2015 at 21:49 Comment(3)
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 to call the frontend save function.Fogel
With IPython < 4, you could do something like: from IPython.display import display,Javascript display(Javascript('IPython.notebook.save_checkpoint();'))Vice
@Taar, thanks! That was the answer I was looking for; would accept as answer if it were answer!Admissible
S
22

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()
Shanel answered 6/9, 2019 at 1:30 Comment(6)
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?Lactone
@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.Shanel
This won't work when using the JupyterLab interface, see here. (Also I think the code should read import time, and not from time import sleep.)Vivien
This unfortunately doesn't work with Jupyter Lab (3.2.5): I get Javascript Error: IPython is not defined.Scevor
this great ! only issue ? : if you save it a second time without changes the hash never changes so it is blocked forever and just hangs. this fixes that: https://mcmap.net/q/465101/-save-an-ipython-notebook-programmatically-from-within-itselfHermetic
Where can I find similar commands to the save_checkpoint command? E.g. save and pin revision (Ctrl+M S)Weiser
R
6

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

Reproachless answered 26/8, 2015 at 22:9 Comment(4)
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.Fogel
or1426, thanks but for some reason I am not getting the output in foo.ipynb, is there any way to do that?Admissible
Is there a way to dynamically add the path to save as well? Eg %notebook path_variable_from_runtime\name.ipynbDrank
if some_python_var is a python variable with the path you want, you can %notebook $some_python_varAsterism
H
0

In [1]:

import os
import time
import pathlib
from IPython.display import display, HTML, Javascript

html = '''
<script>
    IPython.notebook.kernel.execute(
        'filename = "' + IPython.notebook.notebook_name + '"'
    )
</script>
'''

def save_notebook():
    file_path = str(
        pathlib.Path(
            os.getcwd(),
            filename
        )
    )
    start_mtime = os.path.getmtime(file_path)
    display(
        Javascript(
            'IPython.notebook.save_checkpoint();'
        )
    )
    current_mtime = start_mtime
    while start_mtime == current_mtime:
        time.sleep(1)
        current_mtime = os.path.getmtime(file_path)

display(HTML(html))

In [2]:

save_notebook()

This works when you have not made any new changes to the notebook.

Hermetic answered 29/9, 2022 at 3:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.