The API

class delfick_app.App
classmethod main(argv=None, **execute_args)

Instantiates this class and calls the mainline

Usage is intended to be:

from delfick_app import App

class MyApp(App):
    [..]

main = MyApp.main

Attributes

VERSION = <class 'delfick_app.Ignore'>

The version of your application, best way is to define this somewhere and import it into your mainline and setup.py from that location

CliParserKls

The class to use for our CliParser

logging_handler_file

The file to log output to (default is stderr)

boto_useragent_name = <class 'delfick_app.Ignore'>

The name to append to your boto useragent if that’s a thing you want to happen

cli_categories = None

self.execute is passed a dictionary args_dict which is from looking at the args_obj object returned by argparse

This option will break up arguments into hierarchies based on the name of the argument.

For example:

cli_categories = ['app']

and we have arguments for [silent, verbose, debug, app_config, app_option1, app_option2]

Then args_dict will be:

{ "app": {"config": value, "option1": value, "option2": value}
, "silent": value, "verbose": value, "debug": value
}
cli_description = 'My amazing app'

The description to give at the top of –help output

cli_environment_defaults = None

A map of environment variables to –argument that you want to map

For example:

cli_environment_defaults = {"APP_CONFIG": "--config"}

Items may also be a tuple of (replacement, default)

For example, {"APP_CONFIG": ("--config", "./config.yml")}

Which means defaults["--config"] == {'default': "./config.yml"} if APP_CONFIG isn’t in the environment.

cli_positional_replacements = None

A list mapping positional arguments to –arguments

For example:

cli_positional_replacements = ['--environment', '--stack']

Will mean the first positional argument becomes the value for –environment and the second positional becomes the value for ‘–stack’

Note for this to work, you must do something like:

def setup_other_args(self, parser, defaults):
    parser.add_argument('--environment'
        , help = "the environment!"
        , **defaults['--environment']
        )

Items in positional_replacements may also be a tuple of (replacement, default)

For example:

cli_positional_replacements = [('--task', 'list_tasks')]

will mean the first positional argument becomes the value for –task

But if it’s not specified, then defaults['--task'] == {"default": "list_tasks"}

A link to where users can go to post issues

It is used when we get an unexpected exception.

Hooks

execute(args_obj, args_dict, extra_args, logging_handler)

Hook for executing the application itself

setup_other_logging(args_obj, verbose=False, silent=False, debug=False)

Hook for setting up any other logging configuration

For example:

def setup_other_logging(self, args_obj, verbose, silent, debug):
    logging.getLogger("boto").setLevel([logging.CRITICAL, logging.ERROR][verbose or debug])
    logging.getLogger("requests").setLevel([logging.CRITICAL, logging.ERROR][verbose or debug])
    logging.getLogger("paramiko.transport").setLevel([logging.CRITICAL, logging.ERROR][verbose or debug])
specify_other_args(parser, defaults)

Hook for adding more arguments to the argparse Parser

For example:

def specify_other_args(self, parser, defaults):
    parser.add_argument("--special"
        , help = "taste the rainbow"
        , action = "store_true"
        )
exception_handler(exc_info, args_obj, args_dict, extra_args)

Handler for doing things like bugsnag

Argparse Helpers

class delfick_app.DelayedFileType(mode)

Argparse in python2.6 is silly and tries to open the default

So, to get around this, we create an argparse type that returns a function.

Thus delaying opening the file until we have the value that is specified by the commandline:

parser = argparse.ArgumentParser(description="My amazing application")
parser.add_argument("--config"
    , help = "Config file for my amazing application"
    , default = "./fileThatDoesntNecesarilyExist.yml"
    , type = delfick_app.DelayedFileType('r')
    )

args_obj = parser.parse_args(["--config", "./fileThatExists.yml"])
config = args_obj.config()

Command output

delfick_app.command_output(command, *command_extras, **kwargs)

Get the output from a command

Does so in a non blocking fashion and will ensure that the process ends.

Keyword arguments are:

timeout

Defaults to 10, if the process isn’t over by this timeout, it will be sent a SIGTERM

If that doesn’t kill it, a SIGKILL is sent to it

verbose

Defaults to False and makes the command a bit more verbose

stdin

Defaults to None. If specified, it is sent to the process as stdin

Command is split with shlex.split and is prepended to command_extras to create the command for the process

The return of this command is (output, status) where output is the stderr and stdout of the process and status is the exit code of the process.