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