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