From 1184eb4f23d813b1f5fbe5aa26be1dc57b6bb236 2011-12-13 06:38:45 From: Fernando Perez Date: 2011-12-13 06:38:45 Subject: [PATCH] Merge pull request #1146 from minrk/savescript Allow saving notebook.py next to notebook.ipynb. This allows notebooks to be imported or %run via their .py companion file. --- diff --git a/IPython/frontend/html/notebook/notebookmanager.py b/IPython/frontend/html/notebook/notebookmanager.py index 89c0c40..f95b7c4 100644 --- a/IPython/frontend/html/notebook/notebookmanager.py +++ b/IPython/frontend/html/notebook/notebookmanager.py @@ -25,7 +25,7 @@ from tornado import web from IPython.config.configurable import LoggingConfigurable from IPython.nbformat import current -from IPython.utils.traitlets import Unicode, List, Dict +from IPython.utils.traitlets import Unicode, List, Dict, Bool #----------------------------------------------------------------------------- @@ -38,6 +38,15 @@ class NotebookManager(LoggingConfigurable): notebook_dir = Unicode(os.getcwd(), config=True, help=""" The directory to use for notebooks. """) + + save_script = Bool(False, config=True, + help="""Also save notebooks as a Python script. + + For easier use of import/%loadpy across notebooks, a .py + script will be created next to any .ipynb on each save. + """ + ) + filename_ext = Unicode(u'.ipynb') allowed_formats = List([u'json',u'py']) @@ -197,12 +206,25 @@ class NotebookManager(LoggingConfigurable): try: with open(path,'w') as f: current.write(nb, f, u'json') - except: - raise web.HTTPError(400, u'Unexpected error while saving notebook') + except Exception as e: + raise web.HTTPError(400, u'Unexpected error while saving notebook: %s' % e) + # save .py script as well + if self.save_script: + pypath = os.path.splitext(path)[0] + '.py' + try: + with open(pypath,'w') as f: + current.write(nb, f, u'py') + except Exception as e: + raise web.HTTPError(400, u'Unexpected error while saving notebook as script: %s' % e) + if old_name != new_name: old_path = self.get_path_by_name(old_name) if os.path.isfile(old_path): os.unlink(old_path) + if self.save_script: + old_pypath = os.path.splitext(old_path)[0] + '.py' + if os.path.isfile(old_pypath): + os.unlink(old_pypath) self.mapping[notebook_id] = new_name self.rev_mapping[new_name] = notebook_id diff --git a/docs/source/interactive/htmlnotebook.txt b/docs/source/interactive/htmlnotebook.txt index 9bd54c9..b1b6849 100644 --- a/docs/source/interactive/htmlnotebook.txt +++ b/docs/source/interactive/htmlnotebook.txt @@ -188,6 +188,14 @@ prior to import, you manually add the ``# 2`` marker at the start and then add separators for text/code cells, you can get a cleaner import with the file broken into individual cells. +If you want use notebooks as scripts a lot, then you can set:: + + c.NotebookManager.save_script=True + +which will instruct the notebook server to save the ``.py`` export of each +notebook adjacent to the ``.ipynb`` at every save. Then these can be ``%run`` +or imported from regular IPython sessions or other notebooks. + .. warning:: While in simple cases you can roundtrip a notebook to Python, edit the