ipython_save_session.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. """
  4. Borrowed from https://gist.github.com/tgarc/21d2ffe00dab4b3c1075
  5. 1. Add the this script below to your ipython folder (by default $HOME(%HOME%)/.ipython). This script takes care of saving user variables on exit.
  6. 2. Add this line to your profile's ipython startup script (e.g., $HOME/.ipython/profile_default/startup/startup.py):
  7. get_ipython().ex("import ipython_save_session;del ipython_save_session")
  8. 3. In your ipython profile config file (by default $HOME/.ipython/profile_default/ipython_config.py) find the following line:
  9. # c.StoreMagics.autorestore = False
  10. 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.
  11. """
  12. def get_response(quest, default=None, opts=('y', 'n'), please=None, fmt=None):
  13. # try:
  14. # input = raw_input
  15. # except NameError:
  16. # pass
  17. def get_input(_): return str(raw_input(_))
  18. quest += " ("
  19. quest += "/".join(['[' + o + ']' if o == default else o for o in opts])
  20. quest += "): "
  21. if default is not None: opts = list(opts) + ['']
  22. if please is None: please = quest
  23. if fmt is None: fmt = lambda x: x
  24. rin = get_input(quest)
  25. while fmt(rin) not in opts:
  26. print('not in opts(%s), try again' % (opts,))
  27. rin = get_input(please)
  28. return default if default is not None and rin == '' else fmt(rin)
  29. def get_user_vars():
  30. """
  31. Get variables in user namespace (ripped directly from ipython namespace
  32. magic code)
  33. """
  34. import IPython
  35. ip = IPython.get_ipython()
  36. user_ns = ip.user_ns
  37. user_ns_hidden = ip.user_ns_hidden
  38. nonmatching = object()
  39. var_hist = [i for i in user_ns
  40. if not i.startswith('_') \
  41. and (user_ns[i] is not user_ns_hidden.get(i, nonmatching))]
  42. return var_hist
  43. def shutdown_logger():
  44. """
  45. Prompts for saving the current session during shutdown
  46. """
  47. import IPython, pickle, cPickle
  48. var_hist = get_user_vars()
  49. ip = IPython.get_ipython()
  50. db = ip.db
  51. # collect any variables that need to be deleted from db
  52. keys = map(lambda x: x.split('/')[1], db.keys('autorestore/*'))
  53. todel = set(keys).difference(ip.user_ns)
  54. changed = [db[k] != ip.user_ns[k.split('/')[1]]
  55. for k in db.keys('autorestore/*') if k.split('/')[1] in ip.user_ns]
  56. try:
  57. if len(var_hist) == 0 and len(todel) == 0 and not any(changed): return
  58. if get_response("Save session?", 'n', fmt=lambda _ : str(_).lower()) == 'n': return
  59. except KeyboardInterrupt:
  60. return
  61. # Save interactive variables (ignore unsaveable ones)
  62. for name in var_hist:
  63. obj = ip.user_ns[name]
  64. try:
  65. db['autorestore/' + name] = obj
  66. except (pickle.PicklingError, cPickle.PickleError):
  67. print("Could not store variable '%s'. Skipping..." % name)
  68. del db['autorestore/' + name]
  69. # Remove any previously stored variables that were deleted in this session
  70. for k in todel:
  71. del db['autorestore/' + k]
  72. import atexit
  73. atexit.register(shutdown_logger)
  74. del atexit