diff --git a/IPython/frontend/html/notebook/kernelmanager.py b/IPython/frontend/html/notebook/kernelmanager.py index b71ee7a..58b29e1 100644 --- a/IPython/frontend/html/notebook/kernelmanager.py +++ b/IPython/frontend/html/notebook/kernelmanager.py @@ -11,7 +11,7 @@ import uuid import zmq -from IPython.config.configurable import Configurable +from IPython.config.configurable import LoggingConfigurable from IPython.zmq.ipkernel import launch_kernel from IPython.utils.traitlets import Instance, Dict, Unicode @@ -23,17 +23,13 @@ class DuplicateKernelError(Exception): pass -class KernelManager(Configurable): +class KernelManager(LoggingConfigurable): """A class for managing multiple kernels.""" context = Instance('zmq.Context') def _context_default(self): return zmq.Context.instance() - logname = Unicode('') - def _logname_changed(self, name, old, new): - self.log = logging.getLogger(new) - _kernels = Dict() @property @@ -181,6 +177,6 @@ class KernelManager(Configurable): from sessionmanager import SessionManager return SessionManager( kernel_id=kernel_id, kernel_manager=self, - config=self.config, context=self.context, logname=self.logname + config=self.config, context=self.context, log=self.log ) diff --git a/IPython/frontend/html/notebook/notebookapp.py b/IPython/frontend/html/notebook/notebookapp.py index 8ac9856..cf419fc 100644 --- a/IPython/frontend/html/notebook/notebookapp.py +++ b/IPython/frontend/html/notebook/notebookapp.py @@ -6,6 +6,8 @@ import logging import os +import signal +import sys import zmq @@ -16,7 +18,6 @@ import tornado.ioloop tornado.ioloop = ioloop from tornado import httpserver -from tornado import options from tornado import web from kernelmanager import KernelManager @@ -28,7 +29,16 @@ from handlers import ( from routers import IOPubStreamRouter, ShellStreamRouter from IPython.core.application import BaseIPythonApplication +from IPython.core.profiledir import ProfileDir +from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget from IPython.zmq.session import Session +from IPython.zmq.zmqshell import ZMQInteractiveShell +from IPython.zmq.ipkernel import ( + flags as ipkernel_flags, + aliases as ipkernel_aliases, + IPKernelApp +) +from IPython.utils.traitlets import Dict, Unicode, Int, Any, List, Enum #----------------------------------------------------------------------------- # Module globals @@ -37,13 +47,15 @@ from IPython.zmq.session import Session _kernel_id_regex = r"(?P\w+-\w+-\w+-\w+-\w+)" _kernel_action_regex = r"(?Prestart|interrupt)" +LOCALHOST = '127.0.0.1' + #----------------------------------------------------------------------------- # The Tornado web application #----------------------------------------------------------------------------- class NotebookWebApplication(web.Application): - def __init__(self, kernel_manager, log): + def __init__(self, kernel_manager, log, kernel_argv): handlers = [ (r"/", MainHandler), (r"/kernels", KernelHandler), @@ -61,7 +73,9 @@ class NotebookWebApplication(web.Application): self.kernel_manager = kernel_manager self.log = log + self.kernel_argv = kernel_argv self._routers = {} + self._session_dict = {} #------------------------------------------------------------------------- # Methods for managing kernels and sessions @@ -72,9 +86,11 @@ class NotebookWebApplication(web.Application): return self.kernel_manager.kernel_ids def start_kernel(self): - # TODO: pass command line options to the kernel in start_kernel() - kernel_id = self.kernel_manager.start_kernel() + kwargs = dict() + kwargs['extra_arguments'] = self.kernel_argv + kernel_id = self.kernel_manager.start_kernel(**kwargs) self.log.info("Kernel started: %s" % kernel_id) + self.log.debug("Kernel args: %r" % kwargs) self.start_session_manager(kernel_id) return kernel_id @@ -87,7 +103,6 @@ class NotebookWebApplication(web.Application): shell_router = ShellStreamRouter(shell_stream) self._routers[(kernel_id, 'iopub')] = iopub_router self._routers[(kernel_id, 'shell')] = shell_router - self.log.debug("Session manager started for kernel: %s" % kernel_id) def kill_kernel(self, kernel_id): sm = self._session_dict.pop(kernel_id) @@ -139,9 +154,9 @@ aliases = dict(ipkernel_aliases) aliases.update(dict( ip = 'IPythonNotebookApp.ip', - port = 'IPythonNotebookApp.port' + port = 'IPythonNotebookApp.port', colors = 'ZMQInteractiveShell.colors', - editor = 'IPythonWidget.editor', + editor = 'RichIPythonWidget.editor', )) #----------------------------------------------------------------------------- @@ -160,12 +175,17 @@ class IPythonNotebookApp(BaseIPythonApplication): """ classes = [IPKernelApp, ZMQInteractiveShell, ProfileDir, Session, - KernelManager, SessionManager] + KernelManager, SessionManager, RichIPythonWidget] flags = Dict(flags) aliases = Dict(aliases) kernel_argv = List(Unicode) + log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'), + default_value=logging.INFO, + config=True, + help="Set the log level by value or name.") + # connection info: ip = Unicode(LOCALHOST, config=True, help="The IP address the notebook server will listen on." @@ -185,10 +205,10 @@ class IPythonNotebookApp(BaseIPythonApplication): self.kernel_argv = list(argv) # copy # kernel should inherit default config file from frontend - self.kernel_argv.append("KernelApp.parent_appname='%s'"%self.name) + self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name) # scrub frontend-specific flags for a in argv: - if a.startswith('--') and a[2:] in qt_flags: + if a.startswith('-') and a.lstrip('-') in notebook_flags: self.kernel_argv.remove(a) def init_kernel_manager(self): @@ -198,10 +218,17 @@ class IPythonNotebookApp(BaseIPythonApplication): # Create a KernelManager and start a kernel. self.kernel_manager = KernelManager(config=self.config, log=self.log) + def init_logging(self): + super(IPythonNotebookApp, self).init_logging() + # This prevents double log messages because tornado use a root logger that + # self.log is a child of. The logging module dipatches log messages to a log + # and all of its ancenstors until propagate is set to False. + self.log.propagate = False + def initialize(self, argv=None): super(IPythonNotebookApp, self).initialize(argv) - self.init_kernel_mananger() - self.web_app = NotebookWebApplication() + self.init_kernel_manager() + self.web_app = NotebookWebApplication(self.kernel_manager, self.log, self.kernel_argv) self.http_server = httpserver.HTTPServer(self.web_app) self.http_server.listen(self.port) diff --git a/IPython/frontend/html/notebook/sessionmanager.py b/IPython/frontend/html/notebook/sessionmanager.py index 800fd6e..241cf8b 100644 --- a/IPython/frontend/html/notebook/sessionmanager.py +++ b/IPython/frontend/html/notebook/sessionmanager.py @@ -70,7 +70,7 @@ class SessionManager(SessionFactory): def create_connected_stream(self, port, socket_type): sock = self.context.socket(socket_type) addr = "tcp://%s:%i" % (self.kernel_manager.get_kernel_ip(self.kernel_id), port) - self.log.info("Connecting to: %s, %r" % (addr, socket_type)) + self.log.info("Connecting to: %s" % addr) sock.connect(addr) return ZMQStream(sock) diff --git a/IPython/frontend/terminal/ipapp.py b/IPython/frontend/terminal/ipapp.py index 30011e8..eb24136 100755 --- a/IPython/frontend/terminal/ipapp.py +++ b/IPython/frontend/terminal/ipapp.py @@ -195,7 +195,7 @@ class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp): qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp', """Launch the IPython Qt Console.""" ), - hotebook=('IPython.frontend.html.notebook.notebookapp.IPythonNotebookApp', + notebook=('IPython.frontend.html.notebook.notebookapp.IPythonNotebookApp', """Launch the IPython HTML Notebook Server""" ), profile = ("IPython.core.profileapp.ProfileApp",