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