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