storemagic.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. # -*- coding: utf-8 -*-
  2. """
  3. %store magic for lightweight persistence.
  4. Stores variables, aliases and macros in IPython's database.
  5. To automatically restore stored variables at startup, add this to your
  6. :file:`ipython_config.py` file::
  7. c.StoreMagics.autorestore = True
  8. """
  9. from __future__ import print_function
  10. # Copyright (c) IPython Development Team.
  11. # Distributed under the terms of the Modified BSD License.
  12. import inspect, os, sys, textwrap
  13. from IPython.core.error import UsageError
  14. from IPython.core.magic import Magics, magics_class, line_magic
  15. from traitlets import Bool
  16. from IPython.utils.py3compat import string_types
  17. def restore_aliases(ip):
  18. staliases = ip.db.get('stored_aliases', {})
  19. for k,v in staliases.items():
  20. #print "restore alias",k,v # dbg
  21. #self.alias_table[k] = v
  22. ip.alias_manager.define_alias(k,v)
  23. def refresh_variables(ip):
  24. db = ip.db
  25. for key in db.keys('autorestore/*'):
  26. # strip autorestore
  27. justkey = os.path.basename(key)
  28. try:
  29. obj = db[key]
  30. except KeyError:
  31. print("Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey)
  32. print("The error was:", sys.exc_info()[0])
  33. else:
  34. #print "restored",justkey,"=",obj #dbg
  35. ip.user_ns[justkey] = obj
  36. def restore_dhist(ip):
  37. ip.user_ns['_dh'] = ip.db.get('dhist',[])
  38. def restore_data(ip):
  39. refresh_variables(ip)
  40. restore_aliases(ip)
  41. restore_dhist(ip)
  42. @magics_class
  43. class StoreMagics(Magics):
  44. """Lightweight persistence for python variables.
  45. Provides the %store magic."""
  46. autorestore = Bool(False, help=
  47. """If True, any %store-d variables will be automatically restored
  48. when IPython starts.
  49. """
  50. ).tag(config=True)
  51. def __init__(self, shell):
  52. super(StoreMagics, self).__init__(shell=shell)
  53. self.shell.configurables.append(self)
  54. if self.autorestore:
  55. restore_data(self.shell)
  56. @line_magic
  57. def store(self, parameter_s=''):
  58. """Lightweight persistence for python variables.
  59. Example::
  60. In [1]: l = ['hello',10,'world']
  61. In [2]: %store l
  62. In [3]: exit
  63. (IPython session is closed and started again...)
  64. ville@badger:~$ ipython
  65. In [1]: l
  66. NameError: name 'l' is not defined
  67. In [2]: %store -r
  68. In [3]: l
  69. Out[3]: ['hello', 10, 'world']
  70. Usage:
  71. * ``%store`` - Show list of all variables and their current
  72. values
  73. * ``%store spam`` - Store the *current* value of the variable spam
  74. to disk
  75. * ``%store -d spam`` - Remove the variable and its value from storage
  76. * ``%store -z`` - Remove all variables from storage
  77. * ``%store -r`` - Refresh all variables from store (overwrite
  78. current vals)
  79. * ``%store -r spam bar`` - Refresh specified variables from store
  80. (delete current val)
  81. * ``%store foo >a.txt`` - Store value of foo to new file a.txt
  82. * ``%store foo >>a.txt`` - Append value of foo to file a.txt
  83. It should be noted that if you change the value of a variable, you
  84. need to %store it again if you want to persist the new value.
  85. Note also that the variables will need to be pickleable; most basic
  86. python types can be safely %store'd.
  87. Also aliases can be %store'd across sessions.
  88. """
  89. opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
  90. args = argsl.split(None,1)
  91. ip = self.shell
  92. db = ip.db
  93. # delete
  94. if 'd' in opts:
  95. try:
  96. todel = args[0]
  97. except IndexError:
  98. raise UsageError('You must provide the variable to forget')
  99. else:
  100. try:
  101. del db['autorestore/' + todel]
  102. except:
  103. raise UsageError("Can't delete variable '%s'" % todel)
  104. # reset
  105. elif 'z' in opts:
  106. for k in db.keys('autorestore/*'):
  107. del db[k]
  108. elif 'r' in opts:
  109. if args:
  110. for arg in args:
  111. try:
  112. obj = db['autorestore/' + arg]
  113. except KeyError:
  114. print("no stored variable %s" % arg)
  115. else:
  116. ip.user_ns[arg] = obj
  117. else:
  118. restore_data(ip)
  119. # run without arguments -> list variables & values
  120. elif not args:
  121. vars = db.keys('autorestore/*')
  122. vars.sort()
  123. if vars:
  124. size = max(map(len, vars))
  125. else:
  126. size = 0
  127. print('Stored variables and their in-db values:')
  128. fmt = '%-'+str(size)+'s -> %s'
  129. get = db.get
  130. for var in vars:
  131. justkey = os.path.basename(var)
  132. # print 30 first characters from every var
  133. print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50]))
  134. # default action - store the variable
  135. else:
  136. # %store foo >file.txt or >>file.txt
  137. if len(args) > 1 and args[1].startswith('>'):
  138. fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
  139. if args[1].startswith('>>'):
  140. fil = open(fnam, 'a')
  141. else:
  142. fil = open(fnam, 'w')
  143. obj = ip.ev(args[0])
  144. print("Writing '%s' (%s) to file '%s'." % (args[0],
  145. obj.__class__.__name__, fnam))
  146. if not isinstance (obj, string_types):
  147. from pprint import pprint
  148. pprint(obj, fil)
  149. else:
  150. fil.write(obj)
  151. if not obj.endswith('\n'):
  152. fil.write('\n')
  153. fil.close()
  154. return
  155. # %store foo
  156. try:
  157. obj = ip.user_ns[args[0]]
  158. except KeyError:
  159. # it might be an alias
  160. name = args[0]
  161. try:
  162. cmd = ip.alias_manager.retrieve_alias(name)
  163. except ValueError:
  164. raise UsageError("Unknown variable '%s'" % name)
  165. staliases = db.get('stored_aliases',{})
  166. staliases[name] = cmd
  167. db['stored_aliases'] = staliases
  168. print("Alias stored: %s (%s)" % (name, cmd))
  169. return
  170. else:
  171. modname = getattr(inspect.getmodule(obj), '__name__', '')
  172. if modname == '__main__':
  173. print(textwrap.dedent("""\
  174. Warning:%s is %s
  175. Proper storage of interactively declared classes (or instances
  176. of those classes) is not possible! Only instances
  177. of classes in real modules on file system can be %%store'd.
  178. """ % (args[0], obj) ))
  179. return
  180. #pickled = pickle.dumps(obj)
  181. db[ 'autorestore/' + args[0] ] = obj
  182. print("Stored '%s' (%s)" % (args[0], obj.__class__.__name__))
  183. def load_ipython_extension(ip):
  184. """Load the extension in IPython."""
  185. ip.register_magics(StoreMagics)