##// END OF EJS Templates
Fixing minor bug with the logging level in ipapp.py.
Fixing minor bug with the logging level in ipapp.py.

File last commit:

r2270:68974537
r2270:68974537
Show More
application.py
299 lines | 10.9 KiB | text/x-python | PythonLexer
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 #!/usr/bin/env python
# encoding: utf-8
"""
An application for IPython
Authors:
* Brian Granger
* Fernando Perez
Notes
-----
"""
#-----------------------------------------------------------------------------
# Copyright (C) 2008-2009 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
Brian Granger
Work on startup related things....
r2252 import logging
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 import os
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 import sys
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 import traceback
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 from copy import deepcopy
Brian Granger
Massive refactoring of of the core....
r2245
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 from IPython.utils.genutils import get_ipython_dir, filefind
from IPython.config.loader import (
Brian Granger
Massive refactoring of of the core....
r2245 PyFileConfigLoader,
ArgParseConfigLoader,
Config,
NoConfigDefault
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 )
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------
Brian Granger
Massive refactoring of of the core....
r2245 class IPythonArgParseConfigLoader(ArgParseConfigLoader):
"""Default command line options for IPython based applications."""
def _add_other_arguments(self):
self.parser.add_argument('-ipythondir',dest='Global.ipythondir',type=str,
help='Set to override default location of Global.ipythondir.',
default=NoConfigDefault,
metavar='Global.ipythondir')
self.parser.add_argument('-p','-profile',dest='Global.profile',type=str,
help='The string name of the ipython profile to be used.',
default=NoConfigDefault,
metavar='Global.profile')
Brian Granger
Work on startup related things....
r2252 self.parser.add_argument('-log_level',dest="Global.log_level",type=int,
help='Set the log level (0,10,20,30,40,50). Default is 30.',
Brian Granger
Massive refactoring of of the core....
r2245 default=NoConfigDefault)
self.parser.add_argument('-config_file',dest='Global.config_file',type=str,
help='Set the config file name to override default.',
default=NoConfigDefault,
metavar='Global.config_file')
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 class ApplicationError(Exception):
pass
class Application(object):
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 """Load a config, construct an app and run it.
"""
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 config_file_name = 'ipython_config.py'
name = 'ipython'
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
def __init__(self):
Brian Granger
Work on startup related things....
r2252 self.init_logger()
Brian Granger
Don't warn the user if the default config file is missing....
r2257 self.default_config_file_name = self.config_file_name
Brian Granger
Work on startup related things....
r2252
def init_logger(self):
self.log = logging.getLogger(self.__class__.__name__)
# This is used as the default until the command line arguments are read.
self.log.setLevel(logging.WARN)
self._log_handler = logging.StreamHandler()
self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
self._log_handler.setFormatter(self._log_formatter)
self.log.addHandler(self._log_handler)
def _set_log_level(self, level):
self.log.setLevel(level)
def _get_log_level(self):
return self.log.level
log_level = property(_get_log_level, _set_log_level)
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
Brian Granger
Work on Application and loader testing.
r2187 def start(self):
"""Start the application."""
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 self.attempt(self.create_default_config)
self.attempt(self.pre_load_command_line_config)
Brian Granger
More work on getting rid of ipmaker.
r2203 self.attempt(self.load_command_line_config, action='abort')
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 self.attempt(self.post_load_command_line_config)
self.attempt(self.find_ipythondir)
self.attempt(self.find_config_file_name)
self.attempt(self.find_config_file_paths)
self.attempt(self.pre_load_file_config)
self.attempt(self.load_file_config)
self.attempt(self.post_load_file_config)
Brian Granger
Work on Application and loader testing.
r2187 self.attempt(self.merge_configs)
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 self.attempt(self.pre_construct)
Brian Granger
Work on Application and loader testing.
r2187 self.attempt(self.construct)
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 self.attempt(self.post_construct)
Brian Granger
Work on Application and loader testing.
r2187 self.attempt(self.start_app)
#-------------------------------------------------------------------------
# Various stages of Application creation
#-------------------------------------------------------------------------
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 def create_default_config(self):
Brian Granger
All code startup related things are working....
r2253 """Create defaults that can't be set elsewhere.
For the most part, we try to set default in the class attributes
of Components. But, defaults the top-level Application (which is
not a HasTraitlets or Component) are not set in this way. Instead
we set them here. The Global section is for variables like this that
don't belong to a particular component.
"""
Brian Granger
Massive refactoring of of the core....
r2245 self.default_config = Config()
self.default_config.Global.ipythondir = get_ipython_dir()
Brian Granger
Work on startup related things....
r2252 self.log.debug('Default config loaded:')
self.log.debug(repr(self.default_config))
Brian Granger
Semi-final Application and minor work on traitlets.
r2200
Brian Granger
Work on Application and loader testing.
r2187 def create_command_line_config(self):
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 """Create and return a command line config loader."""
return IPythonArgParseConfigLoader(description=self.name)
def pre_load_command_line_config(self):
"""Do actions just before loading the command line config."""
pass
Brian Granger
Work on Application and loader testing.
r2187
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 def load_command_line_config(self):
"""Load the command line config.
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 This method also sets ``self.debug``.
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 """
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 loader = self.create_command_line_config()
self.command_line_config = loader.load_config()
Brian Granger
All code startup related things are working....
r2253 self.extra_args = loader.get_extra_args()
Brian Granger
Work on startup related things....
r2252
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 try:
Brian Granger
Work on startup related things....
r2252 self.log_level = self.command_line_config.Global.log_level
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 except AttributeError:
Brian Granger
Work on startup related things....
r2252 pass # Use existing value which is set in Application.init_logger.
self.log.debug("Command line config loaded:")
self.log.debug(repr(self.command_line_config))
Brian Granger
Semi-final Application and minor work on traitlets.
r2200
def post_load_command_line_config(self):
"""Do actions just after loading the command line config."""
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 pass
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 def find_ipythondir(self):
"""Set the IPython directory.
This sets ``self.ipythondir``, but the actual value that is passed
to the application is kept in either ``self.default_config`` or
``self.command_line_config``. This also added ``self.ipythondir`` to
``sys.path`` so config files there can be references by other config
files.
"""
try:
Brian Granger
Massive refactoring of of the core....
r2245 self.ipythondir = self.command_line_config.Global.ipythondir
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 except AttributeError:
Brian Granger
Massive refactoring of of the core....
r2245 self.ipythondir = self.default_config.Global.ipythondir
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 sys.path.append(os.path.abspath(self.ipythondir))
Brian Granger
The IPython dir is now created by Application if it doesn't exist.
r2201 if not os.path.isdir(self.ipythondir):
os.makedirs(self.ipythondir, mode = 0777)
Brian Granger
Work on startup related things....
r2252 self.log.debug("IPYTHONDIR set to: %s" % self.ipythondir)
Brian Granger
Semi-final Application and minor work on traitlets.
r2200
def find_config_file_name(self):
"""Find the config file name for this application.
If a profile has been set at the command line, this will resolve
it. The search paths for the config file are set in
:meth:`find_config_file_paths` and then passed to the config file
loader where they are resolved to an absolute path.
"""
Brian Granger
More work on getting rid of ipmaker.
r2203 try:
Brian Granger
Massive refactoring of of the core....
r2245 self.config_file_name = self.command_line_config.Global.config_file
Brian Granger
More work on getting rid of ipmaker.
r2203 except AttributeError:
pass
try:
Brian Granger
Massive refactoring of of the core....
r2245 self.profile_name = self.command_line_config.Global.profile
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 name_parts = self.config_file_name.split('.')
name_parts.insert(1, '_' + self.profile_name + '.')
self.config_file_name = ''.join(name_parts)
Brian Granger
More work on getting rid of ipmaker.
r2203 except AttributeError:
pass
Brian Granger
Semi-final Application and minor work on traitlets.
r2200
def find_config_file_paths(self):
"""Set the search paths for resolving the config file."""
self.config_file_paths = (os.getcwd(), self.ipythondir)
def pre_load_file_config(self):
"""Do actions before the config file is loaded."""
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 pass
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 def load_file_config(self):
"""Load the config file.
This tries to load the config file from disk. If successful, the
``CONFIG_FILE`` config variable is set to the resolved config file
location. If not successful, an empty config is used.
"""
Brian Granger
Work on startup related things....
r2252 self.log.debug("Attempting to load config file: <%s>" % self.config_file_name)
Brian Granger
Massive refactoring of of the core....
r2245 loader = PyFileConfigLoader(self.config_file_name,
path=self.config_file_paths)
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 try:
self.file_config = loader.load_config()
Brian Granger
Massive refactoring of of the core....
r2245 self.file_config.Global.config_file = loader.full_filename
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 except IOError:
Brian Granger
Don't warn the user if the default config file is missing....
r2257 # Only warn if the default config file was NOT being used.
if not self.config_file_name==self.default_config_file_name:
self.log.warn("Config file not found, skipping: <%s>" % \
self.config_file_name, exc_info=True)
Brian Granger
Work on startup related things....
r2252 self.file_config = Config()
except:
self.log.warn("Error loading config file: <%s>" % \
self.config_file_name, exc_info=True)
Brian Granger
Massive refactoring of of the core....
r2245 self.file_config = Config()
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 else:
Brian Granger
Work on startup related things....
r2252 self.log.debug("Config file loaded: <%s>" % loader.full_filename)
self.log.debug(repr(self.file_config))
Brian Granger
Fixing minor bug with the logging level in ipapp.py.
r2270 # We need to keeep self.log_level updated. But we only use the value
# of the file_config if a value was not specified at the command
# line.
if not hasattr(self.command_line_config.Global, 'log_level'):
try:
self.log_level = self.file_config.Global.log_level
except AttributeError:
pass # Use existing value
Brian Granger
Semi-final Application and minor work on traitlets.
r2200
def post_load_file_config(self):
"""Do actions after the config file is loaded."""
pass
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
Brian Granger
Work on Application and loader testing.
r2187 def merge_configs(self):
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 """Merge the default, command line and file config objects."""
Brian Granger
Massive refactoring of of the core....
r2245 config = Config()
config._merge(self.default_config)
config._merge(self.file_config)
config._merge(self.command_line_config)
Brian Granger
Work on Application and loader testing.
r2187 self.master_config = config
Brian Granger
Work on startup related things....
r2252 self.log.debug("Master config created:")
self.log.debug(repr(self.master_config))
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 def pre_construct(self):
"""Do actions after the config has been built, but before construct."""
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 pass
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 def construct(self):
"""Construct the main components that make up this app."""
Brian Granger
Work on startup related things....
r2252 self.log.debug("Constructing components for application")
Brian Granger
Semi-final Application and minor work on traitlets.
r2200
def post_construct(self):
"""Do actions after construct, but before starting the app."""
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 pass
def start_app(self):
"""Actually start the app."""
Brian Granger
Work on startup related things....
r2252 self.log.debug("Starting application")
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185
Brian Granger
Work on Application and loader testing.
r2187 #-------------------------------------------------------------------------
# Utility methods
#-------------------------------------------------------------------------
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 def abort(self):
"""Abort the starting of the application."""
Brian Granger
Work on startup related things....
r2252 self.log.critical("Aborting application: %s" % self.name, exc_info=True)
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 sys.exit(1)
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 def exit(self):
Brian Granger
Work on startup related things....
r2252 self.log.critical("Aborting application: %s" % self.name)
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 sys.exit(1)
def attempt(self, func, action='abort'):
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 try:
func()
Brian Granger
Massive refactoring of of the core....
r2245 except SystemExit:
self.exit()
Brian Granger
Working version of the new config loaders for .py files and argparse.
r2185 except:
Brian Granger
Semi-final Application and minor work on traitlets.
r2200 if action == 'abort':
self.abort()
elif action == 'exit':
self.exit()
Brian Granger
Work on startup related things....
r2252