##// END OF EJS Templates
Stripping notebook server flags from kernel's argv.
Brian E. Granger -
Show More
@@ -1,261 +1,270 b''
1 1 """A tornado based IPython notebook server."""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2011 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING.txt, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 import errno
15 15 import logging
16 16 import os
17 17 import signal
18 18 import socket
19 19 import sys
20 20
21 21 import zmq
22 22
23 23 # Install the pyzmq ioloop. This has to be done before anything else from
24 24 # tornado is imported.
25 25 from zmq.eventloop import ioloop
26 26 import tornado.ioloop
27 27 tornado.ioloop = ioloop
28 28
29 29 from tornado import httpserver
30 30 from tornado import web
31 31
32 32 from .kernelmanager import MappingKernelManager
33 33 from .handlers import (
34 34 NBBrowserHandler, NewHandler, NamedNotebookHandler,
35 35 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
36 36 ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler
37 37 )
38 38 from .notebookmanager import NotebookManager
39 39
40 40 from IPython.core.application import BaseIPythonApplication
41 41 from IPython.core.profiledir import ProfileDir
42 42 from IPython.zmq.session import Session
43 43 from IPython.zmq.zmqshell import ZMQInteractiveShell
44 44 from IPython.zmq.ipkernel import (
45 45 flags as ipkernel_flags,
46 46 aliases as ipkernel_aliases,
47 47 IPKernelApp
48 48 )
49 49 from IPython.utils.traitlets import Dict, Unicode, Int, List, Enum
50 50
51 51 #-----------------------------------------------------------------------------
52 52 # Module globals
53 53 #-----------------------------------------------------------------------------
54 54
55 55 _kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
56 56 _kernel_action_regex = r"(?P<action>restart|interrupt)"
57 57 _notebook_id_regex = r"(?P<notebook_id>\w+-\w+-\w+-\w+-\w+)"
58 58
59 59 LOCALHOST = '127.0.0.1'
60 60
61 61 _examples = """
62 62 ipython notebook # start the notebook
63 63 ipython notebook --profile=sympy # use the sympy profile
64 64 ipython notebook --pylab=inline # pylab in inline plotting mode
65 65 ipython notebook --certfile=mycert.pem # use SSL/TLS certificate
66 66 ipython notebook --port=5555 --ip=* # Listen on port 5555, all interfaces
67 67 """
68 68
69 69 #-----------------------------------------------------------------------------
70 70 # The Tornado web application
71 71 #-----------------------------------------------------------------------------
72 72
73 73 class NotebookWebApplication(web.Application):
74 74
75 75 def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
76 76 handlers = [
77 77 (r"/", NBBrowserHandler),
78 78 (r"/new", NewHandler),
79 79 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
80 80 (r"/kernels", MainKernelHandler),
81 81 (r"/kernels/%s" % _kernel_id_regex, KernelHandler),
82 82 (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
83 83 (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler),
84 84 (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler),
85 85 (r"/notebooks", NotebookRootHandler),
86 86 (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler),
87 87 (r"/rstservice/render", RSTHandler)
88 88 ]
89 89 settings = dict(
90 90 template_path=os.path.join(os.path.dirname(__file__), "templates"),
91 91 static_path=os.path.join(os.path.dirname(__file__), "static"),
92 92 )
93 93 web.Application.__init__(self, handlers, **settings)
94 94
95 95 self.kernel_manager = kernel_manager
96 96 self.log = log
97 97 self.notebook_manager = notebook_manager
98 98 self.ipython_app = ipython_app
99 99
100 100
101 101 #-----------------------------------------------------------------------------
102 102 # Aliases and Flags
103 103 #-----------------------------------------------------------------------------
104 104
105 105 flags = dict(ipkernel_flags)
106 106
107 107 # the flags that are specific to the frontend
108 108 # these must be scrubbed before being passed to the kernel,
109 109 # or it will raise an error on unrecognized flags
110 110 notebook_flags = []
111 111
112 112 aliases = dict(ipkernel_aliases)
113 113
114 114 aliases.update({
115 115 'ip': 'IPythonNotebookApp.ip',
116 116 'port': 'IPythonNotebookApp.port',
117 117 'keyfile': 'IPythonNotebookApp.keyfile',
118 118 'certfile': 'IPythonNotebookApp.certfile',
119 119 'ws-hostname': 'IPythonNotebookApp.ws_hostname',
120 120 'notebook-dir': 'NotebookManager.notebook_dir'
121 121 })
122 122
123 notebook_aliases = [u'port', u'ip', u'keyfile', u'certfile', u'ws-hostname',
124 u'notebook-dir']
125
123 126 #-----------------------------------------------------------------------------
124 127 # IPythonNotebookApp
125 128 #-----------------------------------------------------------------------------
126 129
127 130 class IPythonNotebookApp(BaseIPythonApplication):
128 131
129 132 name = 'ipython-notebook'
130 133 default_config_file_name='ipython_notebook_config.py'
131 134
132 135 description = """
133 136 The IPython HTML Notebook.
134 137
135 138 This launches a Tornado based HTML Notebook Server that serves up an
136 139 HTML5/Javascript Notebook client.
137 140 """
138 141 examples = _examples
139 142
140 143 classes = [IPKernelApp, ZMQInteractiveShell, ProfileDir, Session,
141 144 MappingKernelManager, NotebookManager]
142 145 flags = Dict(flags)
143 146 aliases = Dict(aliases)
144 147
145 148 kernel_argv = List(Unicode)
146 149
147 150 log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
148 151 default_value=logging.INFO,
149 152 config=True,
150 153 help="Set the log level by value or name.")
151 154
152 155 # Network related information.
153 156
154 157 ip = Unicode(LOCALHOST, config=True,
155 158 help="The IP address the notebook server will listen on."
156 159 )
157 160
158 161 def _ip_changed(self, name, old, new):
159 162 if new == u'*': self.ip = u''
160 163
161 164 port = Int(8888, config=True,
162 165 help="The port the notebook server will listen on."
163 166 )
164 167
165 168 ws_hostname = Unicode(LOCALHOST, config=True,
166 169 help="""The FQDN or IP for WebSocket connections. The default will work
167 170 fine when the server is listening on localhost, but this needs to
168 171 be set if the ip option is used. It will be used as the hostname part
169 172 of the WebSocket url: ws://hostname/path."""
170 173 )
171 174
172 175 certfile = Unicode(u'', config=True,
173 176 help="""The full path to an SSL/TLS certificate file."""
174 177 )
175 178
176 179 keyfile = Unicode(u'', config=True,
177 180 help="""The full path to a private key file for usage with SSL/TLS."""
178 181 )
179 182
180 183 def get_ws_url(self):
181 184 """Return the WebSocket URL for this server."""
182 185 if self.certfile:
183 186 prefix = u'wss://'
184 187 else:
185 188 prefix = u'ws://'
186 189 return prefix + self.ws_hostname + u':' + unicode(self.port)
187 190
188 191 def parse_command_line(self, argv=None):
189 192 super(IPythonNotebookApp, self).parse_command_line(argv)
190 193 if argv is None:
191 194 argv = sys.argv[1:]
192 195
193 196 self.kernel_argv = list(argv) # copy
194 197 # kernel should inherit default config file from frontend
195 198 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
196 199 # scrub frontend-specific flags
197 200 for a in argv:
198 201 if a.startswith('-') and a.lstrip('-') in notebook_flags:
199 202 self.kernel_argv.remove(a)
203 for a in argv:
204 if a.startswith('-'):
205 alias = a.lstrip('-').split('=')[0]
206 if alias in notebook_aliases:
207 self.kernel_argv.remove(a)
208 print self.kernel_argv
200 209
201 210 def init_configurables(self):
202 211 # Don't let Qt or ZMQ swallow KeyboardInterupts.
203 212 signal.signal(signal.SIGINT, signal.SIG_DFL)
204 213
205 214 # Create a KernelManager and start a kernel.
206 215 self.kernel_manager = MappingKernelManager(
207 216 config=self.config, log=self.log, kernel_argv=self.kernel_argv
208 217 )
209 218 self.notebook_manager = NotebookManager(config=self.config, log=self.log)
210 219
211 220 def init_logging(self):
212 221 super(IPythonNotebookApp, self).init_logging()
213 222 # This prevents double log messages because tornado use a root logger that
214 223 # self.log is a child of. The logging module dipatches log messages to a log
215 224 # and all of its ancenstors until propagate is set to False.
216 225 self.log.propagate = False
217 226
218 227 def initialize(self, argv=None):
219 228 super(IPythonNotebookApp, self).initialize(argv)
220 229 self.init_configurables()
221 230 self.web_app = NotebookWebApplication(
222 231 self, self.kernel_manager, self.notebook_manager, self.log
223 232 )
224 233 if self.certfile:
225 234 ssl_options = dict(certfile=self.certfile)
226 235 if self.keyfile:
227 236 ssl_options['keyfile'] = self.keyfile
228 237 else:
229 238 ssl_options = None
230 239 self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options)
231 240 if ssl_options is None and not self.ip:
232 241 self.log.critical('WARNING: the notebook server is listening on all IP addresses '
233 242 'but not using any encryption or authentication. This is highly '
234 243 'insecure and not recommended.')
235 244 for i in range(10):
236 245 try:
237 246 port = self.port + i
238 247 self.http_server.listen(port, self.ip)
239 248 except socket.error, e:
240 249 if e.errno != errno.EADDRINUSE:
241 250 raise
242 251 self.log.info('The port %i is already in use, trying: %i' % (port, port+1))
243 252 else:
244 253 self.port = port
245 254 break
246 255
247 256
248 257 def start(self):
249 258 ip = self.ip if self.ip else '[all ip addresses on your system]'
250 259 self.log.info("The IPython Notebook is running at: http://%s:%i" % (ip, self.port))
251 260 ioloop.IOLoop.instance().start()
252 261
253 262 #-----------------------------------------------------------------------------
254 263 # Main entry point
255 264 #-----------------------------------------------------------------------------
256 265
257 266 def launch_new_instance():
258 267 app = IPythonNotebookApp()
259 268 app.initialize()
260 269 app.start()
261 270
General Comments 0
You need to be logged in to leave comments. Login now