diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py
index fb59dc68d..f2d1c53b2 100644
--- a/IPython/html/notebookapp.py
+++ b/IPython/html/notebookapp.py
@@ -190,7 +190,6 @@ class NotebookWebApplication(web.Application):
handlers.extend(load_handlers('notebook.handlers'))
handlers.extend(load_handlers('nbconvert.handlers'))
handlers.extend(load_handlers('kernelspecs.handlers'))
- handlers.extend(load_handlers('terminal.handlers'))
handlers.extend(load_handlers('services.kernels.handlers'))
handlers.extend(load_handlers('services.contents.handlers'))
handlers.extend(load_handlers('services.clusters.handlers'))
@@ -762,6 +761,15 @@ class NotebookApp(BaseIPythonApplication):
proto = 'https' if self.certfile else 'http'
return "%s://%s:%i%s" % (proto, ip, self.port, self.base_url)
+ def init_terminals(self):
+ try:
+ from .terminal import initialize
+ initialize(self.web_app)
+ self.web_app.terminals_available = True
+ except ImportError as e:
+ self.log.info("Terminals not available (error was %s)", e)
+ self.web_app.terminals_available = False
+
def init_signal(self):
if not sys.platform.startswith('win'):
signal.signal(signal.SIGINT, self._handle_sigint)
@@ -841,6 +849,7 @@ class NotebookApp(BaseIPythonApplication):
self.init_configurables()
self.init_components()
self.init_webapp()
+ self.init_terminals()
self.init_signal()
def cleanup_kernels(self):
diff --git a/IPython/html/static/terminal/js/main.js b/IPython/html/static/terminal/js/main.js
index e44a16394..1fb58b3ab 100644
--- a/IPython/html/static/terminal/js/main.js
+++ b/IPython/html/static/terminal/js/main.js
@@ -22,8 +22,9 @@ require([
$("#dummy-screen").hide();
var base_url = utils.get_body_data('baseUrl');
+ var ws_path = utils.get_body_data('wsPath');
var ws_url = location.protocol.replace('http', 'ws') + "//" + location.host
- + base_url + "terminal/websocket";
+ + base_url + ws_path;
var header = $("#header")[0]
function calculate_size() {
diff --git a/IPython/html/templates/terminal.html b/IPython/html/templates/terminal.html
index a2593f1ba..ace19aea1 100644
--- a/IPython/html/templates/terminal.html
+++ b/IPython/html/templates/terminal.html
@@ -10,6 +10,7 @@
{% block params %}
data-base-url="{{base_url}}"
+data-ws-path="{{ws_path}}"
{% endblock %}
diff --git a/IPython/html/terminal/__init__.py b/IPython/html/terminal/__init__.py
index e69de29bb..fc78db306 100644
--- a/IPython/html/terminal/__init__.py
+++ b/IPython/html/terminal/__init__.py
@@ -0,0 +1,14 @@
+import os
+from terminado import NamedTermManager
+from .handlers import TerminalHandler, NewTerminalHandler, TermSocket
+
+def initialize(webapp):
+ shell = os.environ.get('SHELL', 'sh')
+ webapp.terminal_manager = NamedTermManager(shell_command=[shell])
+ handlers = [
+ (r"/terminals/new", NewTerminalHandler),
+ (r"/terminals/(\w+)", TerminalHandler),
+ (r"/terminals/websocket/(\w+)", TermSocket,
+ {'term_manager': webapp.terminal_manager}),
+ ]
+ webapp.add_handlers(".*$", handlers)
\ No newline at end of file
diff --git a/IPython/html/terminal/handlers.py b/IPython/html/terminal/handlers.py
index 4f648617f..60e3d7b53 100644
--- a/IPython/html/terminal/handlers.py
+++ b/IPython/html/terminal/handlers.py
@@ -8,19 +8,17 @@ import terminado
from ..base.handlers import IPythonHandler
class TerminalHandler(IPythonHandler):
- """Render the tree view, listing notebooks, clusters, etc."""
+ """Render the terminal interface."""
@web.authenticated
- def get(self, path='', name=None):
- self.write(self.render_template('terminal.html'))
-
-
-#-----------------------------------------------------------------------------
-# URL to handler mappings
-#-----------------------------------------------------------------------------
+ def get(self, term_name):
+ self.write(self.render_template('terminal.html',
+ ws_path="terminals/websocket/%s" % term_name))
+class NewTerminalHandler(IPythonHandler):
+ """Redirect to a new terminal."""
+ @web.authenticated
+ def get(self):
+ name, _ = self.application.terminal_manager.new_named_terminal()
+ self.redirect("/terminals/%s" % name, permanent=False)
-default_handlers = [
- (r"/terminal", TerminalHandler),
- (r"/terminal/websocket", terminado.TermSocket,
- {'term_manager': terminado.SingleTermManager(shell_command=['bash'])}),
- ]
+TermSocket = terminado.TermSocket