From 84ba421e86ba4dc9eba2ce9be35d7f46bb46a171 Mon Sep 17 00:00:00 2001 From: Kevin Bates Date: Thu, 15 Oct 2020 14:58:19 -0700 Subject: [PATCH] Create auto-named terminals via /terminals/new --- notebook/terminal/handlers.py | 12 +++++- notebook/terminal/tests/test_terminals_api.py | 41 ++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/notebook/terminal/handlers.py b/notebook/terminal/handlers.py index 0bb36df98..06bd10f55 100644 --- a/notebook/terminal/handlers.py +++ b/notebook/terminal/handlers.py @@ -15,14 +15,22 @@ class TerminalHandler(IPythonHandler): """Render the terminal interface.""" @web.authenticated def get(self, term_name): - self.write(self.render_template('terminal.html', - ws_path="terminals/websocket/%s" % term_name)) + if term_name == 'new': + model = self.terminal_manager.create() + term_name = model['name'] + new_path = self.request.path.replace("terminals/new", "terminals/" + term_name) + self.redirect(new_path) + else: + self.write(self.render_template('terminal.html', + ws_path="terminals/websocket/%s" % term_name)) class NewTerminalHandler(IPythonHandler): """Renders a new terminal interface using the named argument.""" @web.authenticated def get(self, term_name): + if term_name == 'new': + raise web.HTTPError(400, "Terminal name 'new' is reserved.") new_path = self.request.path.replace("new/{}".format(term_name), term_name) if term_name in self.terminal_manager.terminals: self.set_header('Location', new_path) diff --git a/notebook/terminal/tests/test_terminals_api.py b/notebook/terminal/tests/test_terminals_api.py index 6b808c5c8..9e0cba82d 100644 --- a/notebook/terminal/tests/test_terminals_api.py +++ b/notebook/terminal/tests/test_terminals_api.py @@ -66,6 +66,41 @@ class TerminalAPITest(NotebookTestBase): self.assertIsInstance(term1, dict) def test_create_terminal_via_get(self): + # Test creation of terminal via GET against terminals/new/ + r = self.term_api._req('GET', 'terminals/new') + self.assertEqual(r.status_code, 200) + + r = self.term_api.get('1') + term1 = r.json() + self.assertEqual(r.status_code, 200) + self.assertIsInstance(term1, dict) + self.assertEqual(term1['name'], '1') + + # hit the same endpoint a second time and ensure a second named terminal is created + r = self.term_api._req('GET', 'terminals/new') + self.assertEqual(r.status_code, 200) + + r = self.term_api.get('2') + term2 = r.json() + self.assertEqual(r.status_code, 200) + self.assertIsInstance(term2, dict) + self.assertEqual(term2['name'], '2') + + r = self.term_api.shutdown('2') + self.assertEqual(r.status_code, 204) + + # Make sure there is 1 terminal running + terminals = self.term_api.list().json() + self.assertEqual(len(terminals), 1) + + r = self.term_api.shutdown('1') + self.assertEqual(r.status_code, 204) + + # Make sure there are no terminals are running + terminals = self.term_api.list().json() + self.assertEqual(len(terminals), 0) + + def test_create_terminal_with_name(self): # Test creation of terminal via GET against terminals/new/ r = self.term_api._req('GET', 'terminals/new/foo') self.assertEqual(r.status_code, 200) @@ -92,7 +127,11 @@ class TerminalAPITest(NotebookTestBase): # Make sure there are no terminals are running terminals = self.term_api.list().json() - self.assertEqual(terminals, []) + self.assertEqual(len(terminals), 0) + + # hit terminals/new/new and ensure that 400 is raised + with assert_http_error(400): + self.term_api._req('GET', 'terminals/new/new') def test_terminal_root_handler(self): # POST request