From 2832a684fdd38baad1467e79b04da1c795104436 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sun, 12 Mar 2017 13:13:21 -0500 Subject: [PATCH 1/4] Use server token to load notebooks --- spyder_notebook/widgets/client.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/spyder_notebook/widgets/client.py b/spyder_notebook/widgets/client.py index 6803de2e..b36688ff 100644 --- a/spyder_notebook/widgets/client.py +++ b/spyder_notebook/widgets/client.py @@ -105,7 +105,6 @@ def show_loading_page(self): self.setHtml(page) - class NotebookClient(QWidget): """ Notebook client for Spyder. @@ -124,7 +123,7 @@ def __init__(self, plugin, name): self.plugin_actions = plugin.get_plugin_actions() self.notebookwidget = NotebookWidget(self) - self.notebookwidget.show_loading_page() + self.notebookwidget.show_blank() self.find_widget = FindReplace(self) self.find_widget.set_editor(self.notebookwidget) @@ -142,14 +141,24 @@ def register(self, server_info): self.path = os.path.relpath(self.name, start=server_info['notebook_dir']) - # Full url used to render the notebook as a web page - self.file_url = url_path_join(server_info['url'], - 'notebooks', - url_escape(self.path.replace('\\','/'))) + # Replace backslashes on Windows + if os.name == 'nt': + self.path = self.path.replace('\\','/') # Server url to send requests to self.server_url = server_info['url'] + # Server token + self.token = server_info.get('token', '') + + # Full url used to render the notebook as a web page + file_arg = url_path_join('/notebooks', url_escape(self.path)) + file_arg = file_arg.replace('/', r'%2F') + + self.file_url = url_path_join(self.server_url, + 'login?token={}&next={}'.format(self.token, + file_arg)) + def go_to(self, url_or_text): """Go to page *address*""" if is_text_string(url_or_text): From 177edffce8a1a93a783cd8a0a9e7d3d52e508937 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sun, 12 Mar 2017 13:13:46 -0500 Subject: [PATCH 2/4] Request notebook 4.3+ for this plugin --- setup.py | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/setup.py b/setup.py index 60dd6448..1bd1530d 100644 --- a/setup.py +++ b/setup.py @@ -16,26 +16,24 @@ from setuptools import find_packages, setup from spyder_notebook import __version__ -REQUIREMENTS = ['spyder>=3', 'notebook'] +REQUIREMENTS = ['spyder>=3', 'notebook>=4.3'] setup( - name='spyder-notebook', - version=__version__, - keywords='spyder jupyter notebook', - url='https://github.com/spyder-ide/spyder-notebook', - license='MIT', - author='Spyder Development Team', - description='Jupyter notebook integration with Spyder', - long_description="This is a initial implementation of " - "the notebook running inside Spyder " - "as a plugin.", - packages=find_packages(exclude=['contrib', 'docs', 'tests*']), - install_requires=REQUIREMENTS, - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Operating System :: OS Independent', - 'Programming Language :: Python 2.7', - 'Programming Language :: Python 3' - ]) + name='spyder-notebook', + version=__version__, + keywords='spyder jupyter notebook', + url='https://github.com/spyder-ide/spyder-notebook', + license='MIT', + author='Spyder Development Team', + description='Jupyter notebook integration with Spyder', + long_description="This package allows the Jupyter notebook " + "to run inside Spyder as a plugin.", + packages=find_packages(exclude=['contrib', 'docs', 'tests*']), + install_requires=REQUIREMENTS, + classifiers=['Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Operating System :: OS Independent', + 'Programming Language :: Python 2.7', + 'Programming Language :: Python 3'] +) From 12bc3e65ac17e8e1dde28da22132d3e559e681cd Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sun, 12 Mar 2017 13:15:55 -0500 Subject: [PATCH 3/4] Make the server to start with an empty password This makes things work if users have set a password on their own --- spyder_notebook/utils/nbopen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spyder_notebook/utils/nbopen.py b/spyder_notebook/utils/nbopen.py index 160e1fbc..dfb8792a 100644 --- a/spyder_notebook/utils/nbopen.py +++ b/spyder_notebook/utils/nbopen.py @@ -50,7 +50,8 @@ def nbopen(filename): print("Starting new server") command = ['jupyter', 'notebook', '--no-browser', - '--notebook-dir={}'.format(nbdir)] + '--notebook-dir={}'.format(nbdir), + '--NotebookApp.password='] proc = subprocess.Popen(command) atexit.register(proc.terminate) From f1397073ea72608fa68ffb7ef20866d60c0357ed Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sun, 12 Mar 2017 13:24:44 -0500 Subject: [PATCH 4/4] Correctly send authenticated requests to the server --- spyder_notebook/widgets/client.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/spyder_notebook/widgets/client.py b/spyder_notebook/widgets/client.py index b36688ff..b35cd908 100644 --- a/spyder_notebook/widgets/client.py +++ b/spyder_notebook/widgets/client.py @@ -135,6 +135,11 @@ def __init__(self, plugin, name): layout.addWidget(self.find_widget) self.setLayout(layout) + def add_token(self, url): + """Add notebook token to a given url.""" + token_url = url + '?token={}'.format(self.token) + return token_url + def register(self, server_info): """Register attributes that can be computed with the server info.""" # Path relative to the server directory @@ -149,15 +154,13 @@ def register(self, server_info): self.server_url = server_info['url'] # Server token - self.token = server_info.get('token', '') + self.token = server_info['token'] - # Full url used to render the notebook as a web page - file_arg = url_path_join('/notebooks', url_escape(self.path)) - file_arg = file_arg.replace('/', r'%2F') + url = url_path_join(self.server_url, 'notebooks', + url_escape(self.path)) - self.file_url = url_path_join(self.server_url, - 'login?token={}&next={}'.format(self.token, - file_arg)) + # Set file url to load this notebook + self.file_url = self.add_token(url) def go_to(self, url_or_text): """Go to page *address*""" @@ -186,22 +189,26 @@ def save(self): def shutdown_kernel(self): """Shutdown the kernel of the client.""" - sessions_url = url_path_join(self.server_url, 'api/sessions') + sessions_url = self.add_token(url_path_join(self.server_url, + 'api/sessions')) sessions_req = requests.get(sessions_url).content.decode() sessions = json.loads(sessions_req) kernel_id = None + if os.name == 'nt': path = self.path.replace('\\', '/') else: path = self.path + for session in sessions: if session['notebook']['path'] == path: kernel_id = session['kernel']['id'] break + if kernel_id: - delete_url = url_path_join(self.server_url, - 'api/kernels/', - kernel_id) + delete_url = self.add_token(url_path_join(self.server_url, + 'api/kernels/', + kernel_id)) delete_req = requests.delete(delete_url) if delete_req.status_code != 204: QMessageBox.warning(