#!/usr/bin/env python # encoding: utf-8 """ An application for IPython Authors: * Brian Granger * Fernando Perez Notes ----- The following directories are relevant in the startup of an app: * The ipythondir. This has a default, but can be set by IPYTHONDIR or at the command line. * The current working directory. * Another runtime directory. With some applications (engine, controller) we need the ability to have different cluster configs. Each of these needs to have its own config, security dir and log dir. We could simply treat these as regular ipython dirs. There are number of ways in which these directories are used: * For config files. * For other assets and resources needed to run. These include plugins, magics, furls files. * For writing various things created at runtime like logs, furl files, etc. Questions: * Can we limit ourselves to 1 config file or do we want to have a sequence of them like IPYTHONDIR->RUNTIMEDIR->CWD? [1] * Do we need a debug mode that has custom exception handling and can drop into pdb upno startup? N * Do we need to use an OutputTrap to capture output and then present it to a user if startup fails? N * Do we want the location of the config file(s) to be independent of the ipython/runtime dir or coupled to it. In other words, can the user select a config file that is outside their runtime/ipython dir. One model is that we could have a very strict model of IPYTHONDIR=runtimed dir= dir used for all config. * Do we install default config files or not? N * attempt needs to either clash or to die """ #----------------------------------------------------------------------------- # 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 #----------------------------------------------------------------------------- import sys from copy import deepcopy from IPython.utils.ipstruct import Struct #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- class ApplicationError(Exception): pass class Application(object): runtime_dirs = [] default_config = Struct() runtime_dir = '' config_file = '' name = '' def __init__(self): pass def start(self): """Start the application.""" self.attempt(self.create_command_line_config) self.attempt(self.find_runtime_dirs) self.attempt(self.create_runtime_dirs) self.attempt(self.find_config_files) self.attempt(self.create_file_configs) self.attempt(self.merge_configs) self.attempt(self.construct) self.attempt(self.start_logging) self.attempt(self.start_app) #------------------------------------------------------------------------- # Various stages of Application creation #------------------------------------------------------------------------- def create_command_line_config(self): """Read the command line args and return its config object.""" self.command_line_config = Struct() def find_runtime_dirs(self): """Find the runtime directory for this application. This should set self.runtime_dir. """ pass def create_runtime_dirs(self): """Create the runtime dirs if they don't exist.""" pass def find_config_files(self): """Find the config file for this application.""" pass def create_file_configs(self): self.file_configs = [Struct()] def merge_configs(self): config = Struct() all_configs = self.file_configs + self.command_line_config for c in all_configs: config.update(c) self.master_config = config def construct(self, config): """Construct the main components that make up this app.""" pass def start_logging(self): """Start logging, if needed, at the last possible moment.""" pass def start_app(self): """Actually start the app.""" pass #------------------------------------------------------------------------- # Utility methods #------------------------------------------------------------------------- def abort(self): """Abort the starting of the application.""" print "Aborting application: ", self.name sys.exit(1) def attempt(self, func): try: func() except: self.handle_error() self.abort() def handle_error(self): print "I am dying!"