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