##// END OF EJS Templates
Backport PR #4171: add nbconvert config file when creating profiles...
MinRK -
Show More
@@ -1,306 +1,310 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for managing IPython profiles.
3 An application for managing IPython profiles.
4
4
5 To be invoked as the `ipython profile` subcommand.
5 To be invoked as the `ipython profile` subcommand.
6
6
7 Authors:
7 Authors:
8
8
9 * Min RK
9 * Min RK
10
10
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
14 # Copyright (C) 2008 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 import os
24 import os
25
25
26 from IPython.config.application import Application
26 from IPython.config.application import Application
27 from IPython.core.application import (
27 from IPython.core.application import (
28 BaseIPythonApplication, base_flags
28 BaseIPythonApplication, base_flags
29 )
29 )
30 from IPython.core.profiledir import ProfileDir
30 from IPython.core.profiledir import ProfileDir
31 from IPython.utils.importstring import import_item
31 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
32 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
32 from IPython.utils.traitlets import Unicode, Bool, Dict
33 from IPython.utils.traitlets import Unicode, Bool, Dict
33
34
34 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
35 # Constants
36 # Constants
36 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
37
38
38 create_help = """Create an IPython profile by name
39 create_help = """Create an IPython profile by name
39
40
40 Create an ipython profile directory by its name or
41 Create an ipython profile directory by its name or
41 profile directory path. Profile directories contain
42 profile directory path. Profile directories contain
42 configuration, log and security related files and are named
43 configuration, log and security related files and are named
43 using the convention 'profile_<name>'. By default they are
44 using the convention 'profile_<name>'. By default they are
44 located in your ipython directory. Once created, you will
45 located in your ipython directory. Once created, you will
45 can edit the configuration files in the profile
46 can edit the configuration files in the profile
46 directory to configure IPython. Most users will create a
47 directory to configure IPython. Most users will create a
47 profile directory by name,
48 profile directory by name,
48 `ipython profile create myprofile`, which will put the directory
49 `ipython profile create myprofile`, which will put the directory
49 in `<ipython_dir>/profile_myprofile`.
50 in `<ipython_dir>/profile_myprofile`.
50 """
51 """
51 list_help = """List available IPython profiles
52 list_help = """List available IPython profiles
52
53
53 List all available profiles, by profile location, that can
54 List all available profiles, by profile location, that can
54 be found in the current working directly or in the ipython
55 be found in the current working directly or in the ipython
55 directory. Profile directories are named using the convention
56 directory. Profile directories are named using the convention
56 'profile_<profile>'.
57 'profile_<profile>'.
57 """
58 """
58 profile_help = """Manage IPython profiles
59 profile_help = """Manage IPython profiles
59
60
60 Profile directories contain
61 Profile directories contain
61 configuration, log and security related files and are named
62 configuration, log and security related files and are named
62 using the convention 'profile_<name>'. By default they are
63 using the convention 'profile_<name>'. By default they are
63 located in your ipython directory. You can create profiles
64 located in your ipython directory. You can create profiles
64 with `ipython profile create <name>`, or see the profiles you
65 with `ipython profile create <name>`, or see the profiles you
65 already have with `ipython profile list`
66 already have with `ipython profile list`
66
67
67 To get started configuring IPython, simply do:
68 To get started configuring IPython, simply do:
68
69
69 $> ipython profile create
70 $> ipython profile create
70
71
71 and IPython will create the default profile in <ipython_dir>/profile_default,
72 and IPython will create the default profile in <ipython_dir>/profile_default,
72 where you can edit ipython_config.py to start configuring IPython.
73 where you can edit ipython_config.py to start configuring IPython.
73
74
74 """
75 """
75
76
76 _list_examples = "ipython profile list # list all profiles"
77 _list_examples = "ipython profile list # list all profiles"
77
78
78 _create_examples = """
79 _create_examples = """
79 ipython profile create foo # create profile foo w/ default config files
80 ipython profile create foo # create profile foo w/ default config files
80 ipython profile create foo --reset # restage default config files over current
81 ipython profile create foo --reset # restage default config files over current
81 ipython profile create foo --parallel # also stage parallel config files
82 ipython profile create foo --parallel # also stage parallel config files
82 """
83 """
83
84
84 _main_examples = """
85 _main_examples = """
85 ipython profile create -h # show the help string for the create subcommand
86 ipython profile create -h # show the help string for the create subcommand
86 ipython profile list -h # show the help string for the list subcommand
87 ipython profile list -h # show the help string for the list subcommand
87
88
88 ipython locate profile foo # print the path to the directory for profile 'foo'
89 ipython locate profile foo # print the path to the directory for profile 'foo'
89 """
90 """
90
91
91 #-----------------------------------------------------------------------------
92 #-----------------------------------------------------------------------------
92 # Profile Application Class (for `ipython profile` subcommand)
93 # Profile Application Class (for `ipython profile` subcommand)
93 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
94
95
95
96
96 def list_profiles_in(path):
97 def list_profiles_in(path):
97 """list profiles in a given root directory"""
98 """list profiles in a given root directory"""
98 files = os.listdir(path)
99 files = os.listdir(path)
99 profiles = []
100 profiles = []
100 for f in files:
101 for f in files:
101 full_path = os.path.join(path, f)
102 full_path = os.path.join(path, f)
102 if os.path.isdir(full_path) and f.startswith('profile_'):
103 if os.path.isdir(full_path) and f.startswith('profile_'):
103 profiles.append(f.split('_',1)[-1])
104 profiles.append(f.split('_',1)[-1])
104 return profiles
105 return profiles
105
106
106
107
107 def list_bundled_profiles():
108 def list_bundled_profiles():
108 """list profiles that are bundled with IPython."""
109 """list profiles that are bundled with IPython."""
109 path = os.path.join(get_ipython_package_dir(), u'config', u'profile')
110 path = os.path.join(get_ipython_package_dir(), u'config', u'profile')
110 files = os.listdir(path)
111 files = os.listdir(path)
111 profiles = []
112 profiles = []
112 for profile in files:
113 for profile in files:
113 full_path = os.path.join(path, profile)
114 full_path = os.path.join(path, profile)
114 if os.path.isdir(full_path) and profile != "__pycache__":
115 if os.path.isdir(full_path) and profile != "__pycache__":
115 profiles.append(profile)
116 profiles.append(profile)
116 return profiles
117 return profiles
117
118
118
119
119 class ProfileLocate(BaseIPythonApplication):
120 class ProfileLocate(BaseIPythonApplication):
120 description = """print the path an IPython profile dir"""
121 description = """print the path an IPython profile dir"""
121
122
122 def parse_command_line(self, argv=None):
123 def parse_command_line(self, argv=None):
123 super(ProfileLocate, self).parse_command_line(argv)
124 super(ProfileLocate, self).parse_command_line(argv)
124 if self.extra_args:
125 if self.extra_args:
125 self.profile = self.extra_args[0]
126 self.profile = self.extra_args[0]
126
127
127 def start(self):
128 def start(self):
128 print self.profile_dir.location
129 print self.profile_dir.location
129
130
130
131
131 class ProfileList(Application):
132 class ProfileList(Application):
132 name = u'ipython-profile'
133 name = u'ipython-profile'
133 description = list_help
134 description = list_help
134 examples = _list_examples
135 examples = _list_examples
135
136
136 aliases = Dict({
137 aliases = Dict({
137 'ipython-dir' : 'ProfileList.ipython_dir',
138 'ipython-dir' : 'ProfileList.ipython_dir',
138 'log-level' : 'Application.log_level',
139 'log-level' : 'Application.log_level',
139 })
140 })
140 flags = Dict(dict(
141 flags = Dict(dict(
141 debug = ({'Application' : {'log_level' : 0}},
142 debug = ({'Application' : {'log_level' : 0}},
142 "Set Application.log_level to 0, maximizing log output."
143 "Set Application.log_level to 0, maximizing log output."
143 )
144 )
144 ))
145 ))
145
146
146 ipython_dir = Unicode(get_ipython_dir(), config=True,
147 ipython_dir = Unicode(get_ipython_dir(), config=True,
147 help="""
148 help="""
148 The name of the IPython directory. This directory is used for logging
149 The name of the IPython directory. This directory is used for logging
149 configuration (through profiles), history storage, etc. The default
150 configuration (through profiles), history storage, etc. The default
150 is usually $HOME/.ipython. This options can also be specified through
151 is usually $HOME/.ipython. This options can also be specified through
151 the environment variable IPYTHONDIR.
152 the environment variable IPYTHONDIR.
152 """
153 """
153 )
154 )
154
155
155
156
156 def _print_profiles(self, profiles):
157 def _print_profiles(self, profiles):
157 """print list of profiles, indented."""
158 """print list of profiles, indented."""
158 for profile in profiles:
159 for profile in profiles:
159 print ' %s' % profile
160 print ' %s' % profile
160
161
161 def list_profile_dirs(self):
162 def list_profile_dirs(self):
162 profiles = list_bundled_profiles()
163 profiles = list_bundled_profiles()
163 if profiles:
164 if profiles:
164 print
165 print
165 print "Available profiles in IPython:"
166 print "Available profiles in IPython:"
166 self._print_profiles(profiles)
167 self._print_profiles(profiles)
167 print
168 print
168 print " The first request for a bundled profile will copy it"
169 print " The first request for a bundled profile will copy it"
169 print " into your IPython directory (%s)," % self.ipython_dir
170 print " into your IPython directory (%s)," % self.ipython_dir
170 print " where you can customize it."
171 print " where you can customize it."
171
172
172 profiles = list_profiles_in(self.ipython_dir)
173 profiles = list_profiles_in(self.ipython_dir)
173 if profiles:
174 if profiles:
174 print
175 print
175 print "Available profiles in %s:" % self.ipython_dir
176 print "Available profiles in %s:" % self.ipython_dir
176 self._print_profiles(profiles)
177 self._print_profiles(profiles)
177
178
178 profiles = list_profiles_in(os.getcwdu())
179 profiles = list_profiles_in(os.getcwdu())
179 if profiles:
180 if profiles:
180 print
181 print
181 print "Available profiles in current directory (%s):" % os.getcwdu()
182 print "Available profiles in current directory (%s):" % os.getcwdu()
182 self._print_profiles(profiles)
183 self._print_profiles(profiles)
183
184
184 print
185 print
185 print "To use any of the above profiles, start IPython with:"
186 print "To use any of the above profiles, start IPython with:"
186 print " ipython --profile=<name>"
187 print " ipython --profile=<name>"
187 print
188 print
188
189
189 def start(self):
190 def start(self):
190 self.list_profile_dirs()
191 self.list_profile_dirs()
191
192
192
193
193 create_flags = {}
194 create_flags = {}
194 create_flags.update(base_flags)
195 create_flags.update(base_flags)
195 # don't include '--init' flag, which implies running profile create in other apps
196 # don't include '--init' flag, which implies running profile create in other apps
196 create_flags.pop('init')
197 create_flags.pop('init')
197 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
198 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
198 "reset config files in this profile to the defaults.")
199 "reset config files in this profile to the defaults.")
199 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
200 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
200 "Include the config files for parallel "
201 "Include the config files for parallel "
201 "computing apps (ipengine, ipcontroller, etc.)")
202 "computing apps (ipengine, ipcontroller, etc.)")
202
203
203
204
204 class ProfileCreate(BaseIPythonApplication):
205 class ProfileCreate(BaseIPythonApplication):
205 name = u'ipython-profile'
206 name = u'ipython-profile'
206 description = create_help
207 description = create_help
207 examples = _create_examples
208 examples = _create_examples
208 auto_create = Bool(True, config=False)
209 auto_create = Bool(True, config=False)
210 def _log_format_default(self):
211 return "[%(name)s] %(message)s"
209
212
210 def _copy_config_files_default(self):
213 def _copy_config_files_default(self):
211 return True
214 return True
212
215
213 parallel = Bool(False, config=True,
216 parallel = Bool(False, config=True,
214 help="whether to include parallel computing config files")
217 help="whether to include parallel computing config files")
215 def _parallel_changed(self, name, old, new):
218 def _parallel_changed(self, name, old, new):
216 parallel_files = [ 'ipcontroller_config.py',
219 parallel_files = [ 'ipcontroller_config.py',
217 'ipengine_config.py',
220 'ipengine_config.py',
218 'ipcluster_config.py'
221 'ipcluster_config.py'
219 ]
222 ]
220 if new:
223 if new:
221 for cf in parallel_files:
224 for cf in parallel_files:
222 self.config_files.append(cf)
225 self.config_files.append(cf)
223 else:
226 else:
224 for cf in parallel_files:
227 for cf in parallel_files:
225 if cf in self.config_files:
228 if cf in self.config_files:
226 self.config_files.remove(cf)
229 self.config_files.remove(cf)
227
230
228 def parse_command_line(self, argv):
231 def parse_command_line(self, argv):
229 super(ProfileCreate, self).parse_command_line(argv)
232 super(ProfileCreate, self).parse_command_line(argv)
230 # accept positional arg as profile name
233 # accept positional arg as profile name
231 if self.extra_args:
234 if self.extra_args:
232 self.profile = self.extra_args[0]
235 self.profile = self.extra_args[0]
233
236
234 flags = Dict(create_flags)
237 flags = Dict(create_flags)
235
238
236 classes = [ProfileDir]
239 classes = [ProfileDir]
237
240
241 def _import_app(self, app_path):
242 """import an app class"""
243 app = None
244 name = app_path.rsplit('.', 1)[-1]
245 try:
246 app = import_item(app_path)
247 except ImportError as e:
248 self.log.info("Couldn't import %s, config file will be excluded", name)
249 except Exception:
250 self.log.warn('Unexpected error importing %s', name, exc_info=True)
251 return app
252
238 def init_config_files(self):
253 def init_config_files(self):
239 super(ProfileCreate, self).init_config_files()
254 super(ProfileCreate, self).init_config_files()
240 # use local imports, since these classes may import from here
255 # use local imports, since these classes may import from here
241 from IPython.terminal.ipapp import TerminalIPythonApp
256 from IPython.terminal.ipapp import TerminalIPythonApp
242 apps = [TerminalIPythonApp]
257 apps = [TerminalIPythonApp]
243 try:
258 for app_path in (
244 from IPython.qt.console.qtconsoleapp import IPythonQtConsoleApp
259 'IPython.qt.console.qtconsoleapp.IPythonQtConsoleApp',
245 except Exception:
260 'IPython.html.notebookapp.NotebookApp',
246 # this should be ImportError, but under weird circumstances
261 'IPython.nbconvert.nbconvertapp.NbConvertApp',
247 # this might be an AttributeError, or possibly others
262 ):
248 # in any case, nothing should cause the profile creation to crash.
263 app = self._import_app(app_path)
249 pass
264 if app is not None:
250 else:
265 apps.append(app)
251 apps.append(IPythonQtConsoleApp)
252 try:
253 from IPython.html.notebookapp import NotebookApp
254 except ImportError:
255 pass
256 except Exception:
257 self.log.debug('Unexpected error when importing NotebookApp',
258 exc_info=True
259 )
260 else:
261 apps.append(NotebookApp)
262 if self.parallel:
266 if self.parallel:
263 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
267 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
264 from IPython.parallel.apps.ipengineapp import IPEngineApp
268 from IPython.parallel.apps.ipengineapp import IPEngineApp
265 from IPython.parallel.apps.ipclusterapp import IPClusterStart
269 from IPython.parallel.apps.ipclusterapp import IPClusterStart
266 from IPython.parallel.apps.iploggerapp import IPLoggerApp
270 from IPython.parallel.apps.iploggerapp import IPLoggerApp
267 apps.extend([
271 apps.extend([
268 IPControllerApp,
272 IPControllerApp,
269 IPEngineApp,
273 IPEngineApp,
270 IPClusterStart,
274 IPClusterStart,
271 IPLoggerApp,
275 IPLoggerApp,
272 ])
276 ])
273 for App in apps:
277 for App in apps:
274 app = App()
278 app = App()
275 app.config.update(self.config)
279 app.config.update(self.config)
276 app.log = self.log
280 app.log = self.log
277 app.overwrite = self.overwrite
281 app.overwrite = self.overwrite
278 app.copy_config_files=True
282 app.copy_config_files=True
279 app.profile = self.profile
283 app.profile = self.profile
280 app.init_profile_dir()
284 app.init_profile_dir()
281 app.init_config_files()
285 app.init_config_files()
282
286
283 def stage_default_config_file(self):
287 def stage_default_config_file(self):
284 pass
288 pass
285
289
286
290
287 class ProfileApp(Application):
291 class ProfileApp(Application):
288 name = u'ipython-profile'
292 name = u'ipython-profile'
289 description = profile_help
293 description = profile_help
290 examples = _main_examples
294 examples = _main_examples
291
295
292 subcommands = Dict(dict(
296 subcommands = Dict(dict(
293 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
297 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
294 list = (ProfileList, ProfileList.description.splitlines()[0]),
298 list = (ProfileList, ProfileList.description.splitlines()[0]),
295 ))
299 ))
296
300
297 def start(self):
301 def start(self):
298 if self.subapp is None:
302 if self.subapp is None:
299 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
303 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
300 print
304 print
301 self.print_description()
305 self.print_description()
302 self.print_subcommands()
306 self.print_subcommands()
303 self.exit(1)
307 self.exit(1)
304 else:
308 else:
305 return self.subapp.start()
309 return self.subapp.start()
306
310
General Comments 0
You need to be logged in to leave comments. Login now