Skip to content

Instantly share code, notes, and snippets.

@tgarc
Last active December 20, 2021 08:25
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tgarc/21d2ffe00dab4b3c1075 to your computer and use it in GitHub Desktop.
Save tgarc/21d2ffe00dab4b3c1075 to your computer and use it in GitHub Desktop.
automatically save ipython sessions

I often like to start my ipython session from where I last left off - similar to saving a firefox browsing session. IPython already automatically saves your input history so that you can look up commands in your history, but it doesn't save your variables. Here are the steps to save the state of your variables on exit and have them loaded on startup:

  1. Add the save_user_variables.py script below to your ipython folder (by default $HOME/.ipython). This script takes care of saving user variables on exit.

  2. Add this line to your profile's ipython startup script (e.g., $HOME/.ipython/profile_default/startup/startup.py):
    get_ipython().ex("import save_user_variables;del save_user_variables")

  3. In your ipython profile config file (by default $HOME/.ipython/profile_default/ipython_config.py) find the following line:
    # c.StoreMagics.autorestore = False
    Uncomment it and set it to true. This automatically reloads stored variables on startup. Alternatively you can use reload the last session manually using %store -r.

FYI this was tested using IPython version 2.1.0 in linux mint.

def get_response(quest,default=None,opts=('y','n'),please=None,fmt=None):
try:
raw_input = input
except NameError:
pass
quest += " ("
quest += "/".join(['['+o+']' if o==default else o for o in opts])
quest += "): "
if default is not None: opts = list(opts)+['']
if please is None: please = quest
if fmt is None: fmt = lambda x: x
rin = input(quest)
while fmt(rin) not in opts: rin = input(please)
return default if default is not None and rin == '' else fmt(rin)
def get_user_vars():
"""
Get variables in user namespace (ripped directly from ipython namespace
magic code)
"""
import IPython
ip = IPython.get_ipython()
user_ns = ip.user_ns
user_ns_hidden = ip.user_ns_hidden
nonmatching = object()
var_hist = [ i for i in user_ns
if not i.startswith('_') \
and (user_ns[i] is not user_ns_hidden.get(i, nonmatching)) ]
return var_hist
def shutdown_logger():
"""
Prompts for saving the current session during shutdown
"""
import IPython, pickle
var_hist = get_user_vars()
ip = IPython.get_ipython()
db = ip.db
# collect any variables that need to be deleted from db
keys = map(lambda x: x.split('/')[1], db.keys('autorestore/*'))
todel = set(keys).difference(ip.user_ns)
changed = [db[k] != ip.user_ns[k.split('/')[1]]
for k in db.keys('autorestore/*') if k.split('/')[1] in ip.user_ns]
try:
if len(var_hist) == 0 and len(todel) == 0 and not any(changed): return
if get_response("Save session?", 'n', fmt=str.lower) == 'n': return
except KeyboardInterrupt:
return
# Save interactive variables (ignore unsaveable ones)
for name in var_hist:
obj = ip.user_ns[name]
try:
db[ 'autorestore/' + name ] = obj
except pickle.PicklingError:
print("Could not store variable '%s'. Skipping..." % name)
del db[ 'autorestore/' + name ]
# Remove any previously stored variables that were deleted in this session
for k in todel:
del db['autorestore/'+k]
import atexit
atexit.register(shutdown_logger)
del atexit
@alphaCTzo7G
Copy link

@tgarc, saw your answer on Stackoverflow on how to save variable on exit, using the above script.

does this still work with Ipython 6.0 or recent ones? I tried on Windows 10, ipython 6, and it didnt work..

@tgarc
Copy link
Author

tgarc commented Jan 23, 2018

Sorry @alphaCTzo7G your message got buried in my inbox. Try the new edits I made. Works as before using IPython 6 on my windows machine.

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