##// END OF EJS Templates
Updating notebook configuration....
Brian E. Granger -
Show More
@@ -1,240 +1,249 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for managing IPython profiles.
4 4
5 5 To be invoked as the `ipython profile` subcommand.
6 6
7 7 Authors:
8 8
9 9 * Min RK
10 10
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008-2011 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import logging
25 25 import os
26 26
27 27 from IPython.config.application import Application, boolean_flag
28 28 from IPython.core.application import (
29 29 BaseIPythonApplication, base_flags, base_aliases
30 30 )
31 31 from IPython.core.profiledir import ProfileDir
32 32 from IPython.utils.path import get_ipython_dir
33 33 from IPython.utils.traitlets import Unicode, Bool, Dict
34 34
35 35 #-----------------------------------------------------------------------------
36 36 # Constants
37 37 #-----------------------------------------------------------------------------
38 38
39 39 create_help = """Create an IPython profile by name
40 40
41 41 Create an ipython profile directory by its name or
42 42 profile directory path. Profile directories contain
43 43 configuration, log and security related files and are named
44 44 using the convention 'profile_<name>'. By default they are
45 45 located in your ipython directory. Once created, you will
46 46 can edit the configuration files in the profile
47 47 directory to configure IPython. Most users will create a
48 48 profile directory by name,
49 49 `ipython profile create myprofile`, which will put the directory
50 50 in `<ipython_dir>/profile_myprofile`.
51 51 """
52 52 list_help = """List available IPython profiles
53 53
54 54 List all available profiles, by profile location, that can
55 55 be found in the current working directly or in the ipython
56 56 directory. Profile directories are named using the convention
57 57 'profile_<profile>'.
58 58 """
59 59 profile_help = """Manage IPython profiles
60 60
61 61 Profile directories contain
62 62 configuration, log and security related files and are named
63 63 using the convention 'profile_<name>'. By default they are
64 64 located in your ipython directory. You can create profiles
65 65 with `ipython profile create <name>`, or see the profiles you
66 66 already have with `ipython profile list`
67 67
68 68 To get started configuring IPython, simply do:
69 69
70 70 $> ipython profile create
71 71
72 72 and IPython will create the default profile in <ipython_dir>/profile_default,
73 73 where you can edit ipython_config.py to start configuring IPython.
74 74
75 75 """
76 76
77 77 _list_examples = "ipython profile list # list all profiles"
78 78
79 79 _create_examples = """
80 80 ipython profile create foo # create profile foo w/ default config files
81 81 ipython profile create foo --reset # restage default config files over current
82 82 ipython profile create foo --parallel # also stage parallel config files
83 83 """
84 84
85 85 _main_examples = """
86 86 ipython profile create -h # show the help string for the create subcommand
87 87 ipython profile list -h # show the help string for the list subcommand
88 88 """
89 89
90 90 #-----------------------------------------------------------------------------
91 91 # Profile Application Class (for `ipython profile` subcommand)
92 92 #-----------------------------------------------------------------------------
93 93
94 94
95 95 class ProfileList(Application):
96 96 name = u'ipython-profile'
97 97 description = list_help
98 98 examples = _list_examples
99 99
100 100 aliases = Dict({
101 101 'ipython-dir' : 'ProfileList.ipython_dir',
102 102 'log-level' : 'Application.log_level',
103 103 })
104 104 flags = Dict(dict(
105 105 debug = ({'Application' : {'log_level' : 0}},
106 106 "Set Application.log_level to 0, maximizing log output."
107 107 )
108 108 ))
109 109
110 110 ipython_dir = Unicode(get_ipython_dir(), config=True,
111 111 help="""
112 112 The name of the IPython directory. This directory is used for logging
113 113 configuration (through profiles), history storage, etc. The default
114 114 is usually $HOME/.ipython. This options can also be specified through
115 115 the environment variable IPYTHON_DIR.
116 116 """
117 117 )
118 118
119 119 def list_profile_dirs(self):
120 120 # Find the search paths
121 121 paths = [os.getcwdu(), self.ipython_dir]
122 122
123 123 self.log.warn('Searching for IPython profiles in paths: %r' % paths)
124 124 for path in paths:
125 125 files = os.listdir(path)
126 126 for f in files:
127 127 full_path = os.path.join(path, f)
128 128 if os.path.isdir(full_path) and f.startswith('profile_'):
129 129 profile = f.split('_',1)[-1]
130 130 start_cmd = 'ipython profile=%s' % profile
131 131 print start_cmd + " ==> " + full_path
132 132
133 133 def start(self):
134 134 self.list_profile_dirs()
135 135
136 136
137 137 create_flags = {}
138 138 create_flags.update(base_flags)
139 139 # don't include '--init' flag, which implies running profile create in other apps
140 140 create_flags.pop('init')
141 141 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
142 142 "reset config files in this profile to the defaults.")
143 143 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
144 144 "Include the config files for parallel "
145 145 "computing apps (ipengine, ipcontroller, etc.)")
146 146
147 147
148 148 class ProfileCreate(BaseIPythonApplication):
149 149 name = u'ipython-profile'
150 150 description = create_help
151 151 examples = _create_examples
152 152 auto_create = Bool(True, config=False)
153 153
154 154 def _copy_config_files_default(self):
155 155 return True
156 156
157 157 parallel = Bool(False, config=True,
158 158 help="whether to include parallel computing config files")
159 159 def _parallel_changed(self, name, old, new):
160 160 parallel_files = [ 'ipcontroller_config.py',
161 161 'ipengine_config.py',
162 162 'ipcluster_config.py'
163 163 ]
164 164 if new:
165 165 for cf in parallel_files:
166 166 self.config_files.append(cf)
167 167 else:
168 168 for cf in parallel_files:
169 169 if cf in self.config_files:
170 170 self.config_files.remove(cf)
171 171
172 172 def parse_command_line(self, argv):
173 173 super(ProfileCreate, self).parse_command_line(argv)
174 174 # accept positional arg as profile name
175 175 if self.extra_args:
176 176 self.profile = self.extra_args[0]
177 177
178 178 flags = Dict(create_flags)
179 179
180 180 classes = [ProfileDir]
181 181
182 182 def init_config_files(self):
183 183 super(ProfileCreate, self).init_config_files()
184 184 # use local imports, since these classes may import from here
185 185 from IPython.frontend.terminal.ipapp import TerminalIPythonApp
186 186 apps = [TerminalIPythonApp]
187 187 try:
188 188 from IPython.frontend.qt.console.qtconsoleapp import IPythonQtConsoleApp
189 189 except Exception:
190 190 # this should be ImportError, but under weird circumstances
191 191 # this might be an AttributeError, or possibly others
192 192 # in any case, nothing should cause the profile creation to crash.
193 193 pass
194 194 else:
195 195 apps.append(IPythonQtConsoleApp)
196 try:
197 from IPython.frontend.html.notebook.notebookapp import IPythonNotebookApp
198 except Exception:
199 # this should be ImportError, but under weird circumstances
200 # this might be an AttributeError, or possibly others
201 # in any case, nothing should cause the profile creation to crash.
202 pass
203 else:
204 apps.append(IPythonNotebookApp)
196 205 if self.parallel:
197 206 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
198 207 from IPython.parallel.apps.ipengineapp import IPEngineApp
199 208 from IPython.parallel.apps.ipclusterapp import IPClusterStart
200 209 from IPython.parallel.apps.iploggerapp import IPLoggerApp
201 210 apps.extend([
202 211 IPControllerApp,
203 212 IPEngineApp,
204 213 IPClusterStart,
205 214 IPLoggerApp,
206 215 ])
207 216 for App in apps:
208 217 app = App()
209 218 app.config.update(self.config)
210 219 app.log = self.log
211 220 app.overwrite = self.overwrite
212 221 app.copy_config_files=True
213 222 app.profile = self.profile
214 223 app.init_profile_dir()
215 224 app.init_config_files()
216 225
217 226 def stage_default_config_file(self):
218 227 pass
219 228
220 229
221 230 class ProfileApp(Application):
222 231 name = u'ipython-profile'
223 232 description = profile_help
224 233 examples = _main_examples
225 234
226 235 subcommands = Dict(dict(
227 236 create = (ProfileCreate, "Create a new profile dir with default config files"),
228 237 list = (ProfileList, "List existing profiles")
229 238 ))
230 239
231 240 def start(self):
232 241 if self.subapp is None:
233 242 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
234 243 print
235 244 self.print_description()
236 245 self.print_subcommands()
237 246 self.exit(1)
238 247 else:
239 248 return self.subapp.start()
240 249
@@ -1,203 +1,235 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 logging
15 15 import os
16 16 import signal
17 17 import sys
18 18
19 19 import zmq
20 20
21 21 # Install the pyzmq ioloop. This has to be done before anything else from
22 22 # tornado is imported.
23 23 from zmq.eventloop import ioloop
24 24 import tornado.ioloop
25 25 tornado.ioloop = ioloop
26 26
27 27 from tornado import httpserver
28 28 from tornado import web
29 29
30 30 from .kernelmanager import KernelManager, RoutingKernelManager
31 31 from .sessionmanager import SessionManager
32 32 from .handlers import (
33 33 NBBrowserHandler, NewHandler, NamedNotebookHandler,
34 34 MainKernelHandler, KernelHandler, KernelActionHandler, ZMQStreamHandler,
35 35 NotebookRootHandler, NotebookHandler, RSTHandler
36 36 )
37 37 from .notebookmanager import NotebookManager
38 38
39 39 from IPython.core.application import BaseIPythonApplication
40 40 from IPython.core.profiledir import ProfileDir
41 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
42 41 from IPython.zmq.session import Session
43 42 from IPython.zmq.zmqshell import ZMQInteractiveShell
44 43 from IPython.zmq.ipkernel import (
45 44 flags as ipkernel_flags,
46 45 aliases as ipkernel_aliases,
47 46 IPKernelApp
48 47 )
49 48 from IPython.utils.traitlets import Dict, Unicode, Int, Any, List, Enum
50 49
51 50 #-----------------------------------------------------------------------------
52 51 # Module globals
53 52 #-----------------------------------------------------------------------------
54 53
55 54 _kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
56 55 _kernel_action_regex = r"(?P<action>restart|interrupt)"
57 56 _notebook_id_regex = r"(?P<notebook_id>\w+-\w+-\w+-\w+-\w+)"
58 57
59 58 LOCALHOST = '127.0.0.1'
60 59
60 _examples = """
61 ipython notebook # start the notebook
62 ipython notebook --profile=sympy # use the sympy profile
63 ipython notebook --pylab=inline # pylab in inline plotting mode
64 ipython notebook --certfile=mycert.pem # use SSL/TLS certificate
65 ipython notebook --port=5555 --ip=* # Listen on port 5555, all interfaces
66 """
67
61 68 #-----------------------------------------------------------------------------
62 69 # The Tornado web application
63 70 #-----------------------------------------------------------------------------
64 71
65 72 class NotebookWebApplication(web.Application):
66 73
67 74 def __init__(self, routing_kernel_manager, notebook_manager, log):
68 75 handlers = [
69 76 (r"/", NBBrowserHandler),
70 77 (r"/new", NewHandler),
71 78 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
72 79 (r"/kernels", MainKernelHandler),
73 80 (r"/kernels/%s" % _kernel_id_regex, KernelHandler),
74 81 (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
75 82 (r"/kernels/%s/iopub" % _kernel_id_regex, ZMQStreamHandler, dict(stream_name='iopub')),
76 83 (r"/kernels/%s/shell" % _kernel_id_regex, ZMQStreamHandler, dict(stream_name='shell')),
77 84 (r"/notebooks", NotebookRootHandler),
78 85 (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler),
79 86 (r"/rstservice/render", RSTHandler)
80 87 ]
81 88 settings = dict(
82 89 template_path=os.path.join(os.path.dirname(__file__), "templates"),
83 90 static_path=os.path.join(os.path.dirname(__file__), "static"),
84 91 )
85 92 web.Application.__init__(self, handlers, **settings)
86 93
87 94 self.routing_kernel_manager = routing_kernel_manager
88 95 self.log = log
89 96 self.notebook_manager = notebook_manager
90 97
91 98
92 99 #-----------------------------------------------------------------------------
93 100 # Aliases and Flags
94 101 #-----------------------------------------------------------------------------
95 102
96 103 flags = dict(ipkernel_flags)
97 104
98 105 # the flags that are specific to the frontend
99 106 # these must be scrubbed before being passed to the kernel,
100 107 # or it will raise an error on unrecognized flags
101 108 notebook_flags = []
102 109
103 110 aliases = dict(ipkernel_aliases)
104 111
105 aliases.update(dict(
106 ip = 'IPythonNotebookApp.ip',
107 port = 'IPythonNotebookApp.port',
108 colors = 'ZMQInteractiveShell.colors',
109 ))
112 aliases.update({
113 'ip': 'IPythonNotebookApp.ip',
114 'port': 'IPythonNotebookApp.port',
115 'keyfile': 'IPythonNotebookApp.keyfile',
116 'certfile': 'IPythonNotebookApp.certfile',
117 'colors': 'ZMQInteractiveShell.colors',
118 'notebook-dir': 'NotebookManager.notebook_dir'
119 })
110 120
111 121 #-----------------------------------------------------------------------------
112 122 # IPythonNotebookApp
113 123 #-----------------------------------------------------------------------------
114 124
115 125 class IPythonNotebookApp(BaseIPythonApplication):
126
116 127 name = 'ipython-notebook'
117 128 default_config_file_name='ipython_notebook_config.py'
118 129
119 130 description = """
120 131 The IPython HTML Notebook.
121 132
122 133 This launches a Tornado based HTML Notebook Server that serves up an
123 134 HTML5/Javascript Notebook client.
124 135 """
136 examples = _examples
125 137
126 138 classes = [IPKernelApp, ZMQInteractiveShell, ProfileDir, Session,
127 139 RoutingKernelManager, NotebookManager,
128 140 KernelManager, SessionManager]
129 141 flags = Dict(flags)
130 142 aliases = Dict(aliases)
131 143
132 144 kernel_argv = List(Unicode)
133 145
134 146 log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
135 147 default_value=logging.INFO,
136 148 config=True,
137 149 help="Set the log level by value or name.")
138 150
139 # connection info:
151 # Network related information.
152
140 153 ip = Unicode(LOCALHOST, config=True,
141 154 help="The IP address the notebook server will listen on."
142 155 )
143 156
157 def _ip_changed(self, name, old, new):
158 if new == u'*': self.ip = u''
159
144 160 port = Int(8888, config=True,
145 161 help="The port the notebook server will listen on."
146 162 )
147 163
148 # the factory for creating a widget
149 widget_factory = Any(RichIPythonWidget)
164 certfile = Unicode(u'', config=True,
165 help="""The full path to an SSL/TLS certificate file."""
166 )
167
168 keyfile = Unicode(u'', config=True,
169 help="""The full path to a private key file for usage with SSL/TLS."""
170 )
150 171
151 172 def parse_command_line(self, argv=None):
152 173 super(IPythonNotebookApp, self).parse_command_line(argv)
153 174 if argv is None:
154 175 argv = sys.argv[1:]
155 176
156 177 self.kernel_argv = list(argv) # copy
157 178 # kernel should inherit default config file from frontend
158 179 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
159 180 # scrub frontend-specific flags
160 181 for a in argv:
161 182 if a.startswith('-') and a.lstrip('-') in notebook_flags:
162 183 self.kernel_argv.remove(a)
163 184
164 185 def init_configurables(self):
165 186 # Don't let Qt or ZMQ swallow KeyboardInterupts.
166 187 signal.signal(signal.SIGINT, signal.SIG_DFL)
167 188
168 189 # Create a KernelManager and start a kernel.
169 190 self.kernel_manager = KernelManager(config=self.config, log=self.log)
170 191 self.routing_kernel_manager = RoutingKernelManager(config=self.config, log=self.log,
171 192 kernel_manager=self.kernel_manager, kernel_argv=self.kernel_argv
172 193 )
173 194 self.notebook_manager = NotebookManager(config=self.config, log=self.log)
174 195
175 196 def init_logging(self):
176 197 super(IPythonNotebookApp, self).init_logging()
177 198 # This prevents double log messages because tornado use a root logger that
178 199 # self.log is a child of. The logging module dipatches log messages to a log
179 200 # and all of its ancenstors until propagate is set to False.
180 201 self.log.propagate = False
181 202
182 203 def initialize(self, argv=None):
183 204 super(IPythonNotebookApp, self).initialize(argv)
184 205 self.init_configurables()
185 206 self.web_app = NotebookWebApplication(
186 207 self.routing_kernel_manager, self.notebook_manager, self.log
187 208 )
188 self.http_server = httpserver.HTTPServer(self.web_app)
189 self.http_server.listen(self.port)
209 if self.certfile:
210 ssl_options = dict(certfile=self.certfile)
211 if self.keyfile:
212 ssl_options['keyfile'] = self.keyfile
213 else:
214 ssl_options = None
215 self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options)
216 if ssl_options is None and not self.ip:
217 self.log.critical('WARNING: the notebook server is listening on all IP addresses '
218 'but not using any encryption or authentication. This is highly '
219 'insecure and not recommended.')
220 self.http_server.listen(self.port, self.ip)
190 221
191 222 def start(self):
192 self.log.info("The IPython Notebook is running at: http://%s:%i" % (self.ip, self.port))
223 ip = self.ip if self.ip else '[all ip addresses on your system]'
224 self.log.info("The IPython Notebook is running at: http://%s:%i" % (ip, self.port))
193 225 ioloop.IOLoop.instance().start()
194 226
195 227 #-----------------------------------------------------------------------------
196 228 # Main entry point
197 229 #-----------------------------------------------------------------------------
198 230
199 231 def launch_new_instance():
200 232 app = IPythonNotebookApp()
201 233 app.initialize()
202 234 app.start()
203 235
General Comments 0
You need to be logged in to leave comments. Login now