Skip to content

Commit ac50d2e

Browse files
committed
Add support for creating terminals via GET
1 parent 1550410 commit ac50d2e

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

notebook/terminal/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ipython_genutils.py3compat import which
1111
from notebook.utils import url_path_join as ujoin
1212
from .terminalmanager import TerminalManager
13-
from .handlers import TerminalHandler, TermSocket
13+
from .handlers import TerminalHandler, TermSocket, NewTerminalHandler
1414
from . import api_handlers
1515

1616

@@ -45,6 +45,7 @@ def initialize(nb_app):
4545
(ujoin(base_url, r"/terminals/(\w+)"), TerminalHandler),
4646
(ujoin(base_url, r"/terminals/websocket/(\w+)"), TermSocket,
4747
{'term_manager': terminal_manager}),
48+
(ujoin(base_url, r"/terminals/new/(\w+)"), NewTerminalHandler),
4849
(ujoin(base_url, r"/api/terminals"), api_handlers.TerminalRootHandler),
4950
(ujoin(base_url, r"/api/terminals/(\w+)"), api_handlers.TerminalHandler),
5051
]

notebook/terminal/handlers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ def get(self, term_name):
1818
ws_path="terminals/websocket/%s" % term_name))
1919

2020

21+
class NewTerminalHandler(IPythonHandler):
22+
"""Render the terminal interface."""
23+
@web.authenticated
24+
def get(self, term_name):
25+
self.terminal_manager.create_with_name(term_name)
26+
new_path = self.request.path.replace("new/{}".format(term_name), term_name)
27+
self.redirect(new_path)
28+
29+
2130
class TermSocket(WebSocketMixin, IPythonHandler, terminado.TermSocket):
2231

2332
def origin_check(self):

notebook/terminal/terminalmanager.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ def __init__(self, *args, **kwargs):
4444
def create(self):
4545
"""Create a new terminal."""
4646
name, term = self.new_named_terminal()
47+
return self._finish_create(name, term)
48+
49+
def create_with_name(self, name):
50+
"""Create a new terminal."""
51+
if name in self.terminals:
52+
raise web.HTTPError(409, "A terminal with name '{}' already exists.".format(name))
53+
term = self.get_terminal(name)
54+
return self._finish_create(name, term)
55+
56+
def _finish_create(self, name, term):
4757
# Monkey-patch last-activity, similar to kernels. Should we need
4858
# more functionality per terminal, we can look into possible sub-
4959
# classing or containment then.

notebook/terminal/tests/test_terminals_api.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def tearDown(self):
5454
self.term_api.shutdown(k['name'])
5555

5656
def test_no_terminals(self):
57-
# Make sure there are no terminals running at the start
57+
# Make sure there are no terminals are running at the start
5858
terminals = self.term_api.list().json()
5959
self.assertEqual(terminals, [])
6060

@@ -65,6 +65,27 @@ def test_create_terminal(self):
6565
self.assertEqual(r.status_code, 200)
6666
self.assertIsInstance(term1, dict)
6767

68+
def test_create_terminal_via_get(self):
69+
# Test creation of terminal via GET against terminals/new/<name>
70+
r = self.term_api._req('GET', 'terminals/new/foo')
71+
self.assertEqual(r.status_code, 200)
72+
73+
r = self.term_api.get('foo')
74+
foo_term = r.json()
75+
self.assertEqual(r.status_code, 200)
76+
self.assertIsInstance(foo_term, dict)
77+
self.assertEqual(foo_term['name'], 'foo')
78+
79+
with assert_http_error(409):
80+
self.term_api._req('GET', 'terminals/new/foo')
81+
82+
r = self.term_api.shutdown('foo')
83+
self.assertEqual(r.status_code, 204)
84+
85+
# Make sure there are no terminals are running
86+
terminals = self.term_api.list().json()
87+
self.assertEqual(terminals, [])
88+
6889
def test_terminal_root_handler(self):
6990
# POST request
7091
r = self.term_api.start()

0 commit comments

Comments
 (0)