cement.core.foundation

Cement core foundation module.

class cement.core.foundation.CementApp(label=None, **kw)

Bases: cement.core.meta.MetaMixin

The primary class to build applications from.

Usage:

The following is the simplest CementApp:

from cement.core.foundation import CementApp

with CementApp('helloworld') as app:
    app.run()

Alternatively, the above could be written as:

from cement.core.foundation import CementApp

app = foundation.CementApp('helloworld')
app.setup()
app.run()
app.close()

A more advanced example looks like:

from cement.core.foundation import CementApp
from cement.core.controller import CementBaseController, expose

class MyController(CementBaseController):
    class Meta:
        label = 'base'
        arguments = [
            ( ['-f', '--foo'], dict(help='Notorious foo option') ),
            ]
        config_defaults = dict(
            debug=False,
            some_config_param='some_value',
            )

    @expose(help='This is the default command', hide=True)
    def default(self):
        print('Hello World')

class MyApp(CementApp):
    class Meta:
        label = 'helloworld'
        extensions = ['daemon','json',]
        base_controller = MyController

with MyApp() as app:
    app.run()
class Meta

Bases: object

Application meta-data (can also be passed as keyword arguments to the parent class).

alternative_module_mapping = {}

EXPERIMENTAL FEATURE: This is an experimental feature added in Cement 2.9.x and may or may not be removed in future versions of Cement.

Dictionary of alternative, drop-in replacement modules to use selectively throughout the application, framework, or extensions. Developers can optionally use the CementApp.__import__() method to import simple modules, and if that module exists in this mapping it will import the alternative library in it’s place.

This is a low-level feature, and may not produce the results you are expecting. It’s purpose is to allow the developer to replace specific modules at a high level. Example: For an application wanting to use ujson in place of json, the developer could set the following:

alternative_module_mapping = {
    'json' : 'ujson',
}

In the app, you would then load json as:

_json = app.__import__('json')
_json.dumps(data)

Obviously, the replacement module must be a drop-in replace and function the same.

argument_handler = 'argparse'

A handler class that implements the IArgument interface.

arguments_override_config = False

A boolean to toggle whether command line arguments should override configuration values if the argument name matches the config key. I.e. –foo=bar would override config[‘myapp’][‘foo’].

This is different from override_arguments in that if arguments_override_config is True, then all arguments will override (you don’t have to list them all).

argv = None

A list of arguments to use for parsing command line arguments and options.

Note: Though Meta.argv defaults to None, Cement will set this to list(sys.argv[1:]) if no argv is set in Meta during setup().

base_controller = None

This is the base application controller. If a controller is set, runtime operations are passed to the controller for command dispatch and argument parsing when CementApp.run() is called.

Note that cement will automatically set the base_controller to a registered controller whose label is ‘base’ (only if base_controller is not currently set).

bootstrap = None

A bootstrapping module to load after app creation, and before app.setup() is called. This is useful for larger applications that need to offload their bootstrapping code such as registering hooks/handlers/etc to another file.

This must be a dotted python module path. I.e. ‘myapp.bootstrap’ (myapp/bootstrap.py). Cement will then import the module, and if the module has a ‘load()’ function, that will also be called. Essentially, this is the same as an extension or plugin, but as a facility for the application itself to bootstrap ‘hardcoded’ application code. It is also called before plugins are loaded.

cache_handler = None

A handler class that implements the ICache interface.

catch_signals = [<Signals.SIGTERM: 15>, <Signals.SIGINT: 2>, <Signals.SIGHUP: 1>]

List of signals to catch, and raise exc.CaughtSignal for. Can be set to None to disable signal handling.

config_defaults = None

Default configuration dictionary. Must be of type ‘dict’.

config_extension = '.conf'

Extension used to identify application and plugin configuration files.

config_files = None

List of config files to parse.

Note: Though Meta.config_section defaults to None, Cement will set this to a default list based on Meta.label (or in other words, the name of the application). This will equate to:

['/etc/<app_label>/<app_label>.conf',
 '~/.<app_label>.conf',
 '~/.<app_label>/config']

Files are loaded in order, and have precedence in order. Therefore, the last configuration loaded has precedence (and overwrites settings loaded from previous configuration files).

Note that .conf is the default config file extension, defined by CementApp.Meta.config_extension.

config_handler = 'configparser'

A handler class that implements the IConfig interface.

config_section = None

The base configuration section for the application.

Note: Though Meta.config_section defaults to None, Cement will set this to the value of Meta.label (or in other words, the name of the application).

core_extensions = ['cement.ext.ext_dummy', 'cement.ext.ext_smtp', 'cement.ext.ext_plugin', 'cement.ext.ext_configparser', 'cement.ext.ext_logging', 'cement.ext.ext_argparse']

List of Cement core extensions. These are generally required by Cement and should only be modified if you know what you’re doing. Use ‘extensions’ to add to this list, rather than overriding core extensions. That said if you want to prune down your application, you can remove core extensions if they are not necessary (for example if using your own log handler extension you likely don’t want/need LoggingLogHandler to be registered).

core_handler_override_options = {'output': (['-o'], {'help': 'output handler'})}

Similar to CementApp.Meta.handler_override_options but these are the core defaults required by Cement. This dictionary can be overridden by CementApp.Meta.handler_override_options (when they are merged together).

core_meta_override = ['debug', 'plugin_config_dir', 'plugin_dir', 'ignore_deprecation_warnings', 'template_dir', 'mail_handler', 'cache_handler', 'log_handler', 'output_handler']

List of meta options that can/will be overridden by config options of the ‘[base]’ config section (where [base] is the base configuration section of the application which is determined by Meta.config_section but defaults to Meta.label). These overrides are required by the framework to function properly and should not be used by end user (developers) unless you really know what you’re doing. To add your own extended meta overrides please use ‘meta_override’.

debug = False

Used internally, and should not be used by developers. This is set to True if –debug is passed at command line.

define_handlers = []

List of interfaces classes to define handlers. Must be a list of uninstantiated interface classes.

I.e. ['MyCustomInterface', 'SomeOtherInterface']

define_hooks = []

List of hook definitions (label). Will be passed to self.hook.define(<hook_label>). Must be a list of strings.

I.e. ['my_custom_hook', 'some_other_hook']

exit_on_close = False

Whether or not to call sys.exit() when close() is called. The default is False, however if True then the app will call sys.exit(X) where X is self.exit_code.

extension_handler = 'cement'

A handler class that implements the IExtension interface.

extensions = []

List of additional framework extensions to load.

framework_logging = True

Whether or not to enable Cement framework logging. This is separate from the application log, and is generally used for debugging issues with the framework and/or extensions primarily in development.

This option is overridden by the environment variable CEMENT_FRAMEWORK_LOGGING. Therefore, if in production you do not want the Cement framework log enabled, you can set this option to False but override it in your environment by doing something like export CEMENT_FRAMEWORK_LOGGING=1 in your shell whenever you need it enabled.

handler_override_options = {}

Dictionary of handler override options that will be added to the argument parser, and allow the end-user to override handlers. Useful for interfaces that have multiple uses within the same application (for example: Output Handler (json, yaml, etc) or maybe a Cloud Provider Handler (rackspace, digitalocean, amazon, etc).

This dictionary will merge with CementApp.Meta.core_handler_override_options but this one has precedence.

Dictionary Format:

<interface_name> = (option_arguments, help_text)

See CementApp.Meta.core_handler_override_options for an example of what this should look like.

Note, if set to None then no options will be defined, and the CementApp.Meta.core_meta_override_options will be ignore (not recommended as some extensions rely on this feature).

handlers = []

List of handler classes to register. Will be passed to handler.register(<handler_class>). Must be a list of uninstantiated handler classes.

I.e. [MyCustomHandler, SomeOtherHandler]

hooks = []

List of hooks to register when the app is created. Will be passed to self.hook.register(<hook_label>, <hook_func>). Must be a list of tuples in the form of (<hook_label>, <hook_func>).

I.e. [('post_argument_parsing', my_hook_func)].

ignore_deprecation_warnings = False

Disable deprecation warnings from being logged by Cement.

label = None

The name of the application. This should be the common name as you would see and use at the command line. For example ‘helloworld’, or ‘my-awesome-app’.

log_handler = 'logging'

A handler class that implements the ILog interface.

mail_handler = 'dummy'

A handler class that implements the IMail interface.

meta_defaults = {}

Default metadata dictionary used to pass high level options from the application down to handlers at the point they are registered by the framework if the handler has not already been instantiated.

For example, if requiring the json extension, you might want to override JsonOutputHandler.Meta.json_module with ujson by doing the following

from cement.core.foundation import CementApp
from cement.utils.misc import init_defaults

META = init_defaults('output.json')
META['output.json']['json_module'] = 'ujson'

class MyApp(CementApp):
    class Meta:
        label = 'myapp'
        extensions = ['json']
        meta_defaults = META
meta_override = []

List of meta options that can/will be overridden by config options of the ‘[base]’ config section (where [base] is the base configuration section of the application which is determined by Meta.config_section but defaults to Meta.label).

output_handler = 'dummy'

A handler class that implements the IOutput interface.

override_arguments = ['debug']

List of arguments that override their configuration counter-part. For example, if --debug is passed (and it’s config value is debug) then the debug key of all configuration sections will be overridden by the value of the command line option (True in this example).

This is different from arguments_override_config in that this is a selective list of specific arguments to override the config with (and not all arguments that match the config). This list will take affect whether arguments_override_config is True or False.

plugin_bootstrap = None

A python package (dotted import path) where plugin code can be loaded from. This is generally something like myapp.plugins where a plugin file would live at myapp/plugins/myplugin.py. This provides a facility for applications that have builtin plugins that ship with the applications source code and live in the same Python module.

Note: Though the meta default is None, Cement will set this to <app_label>.plugins if not set.

plugin_config_dir = None

A directory path where plugin config files can be found. Files must end in .conf (or the extension defined by CementApp.Meta.config_extension) or they will be ignored. By default, this setting is also overridden by the [<app_label>] -> plugin_config_dir config setting parsed in any of the application configuration files.

If set, this item will be appended to CementApp.Meta.plugin_config_dirs so that it’s settings will have presedence over other configuration files.

In general, this setting should not be defined by the developer, as it is primarily used to allow the end-user to define a plugin_config_dir without completely trumping the hard-coded list of default plugin_config_dirs defined by the app/developer.

plugin_config_dirs = None

A list of directory paths where plugin config files can be found. Files must end in .conf (or the extension defined by CementApp.Meta.config_extension) or they will be ignored.

Note: Though CementApp.Meta.plugin_config_dirs is None, Cement will set this to a default list based on CementApp.Meta.label. This will equate to:

['/etc/<app_label>/plugins.d', '~/.<app_label>/plugin.d']

Files are loaded in order, and have precedence in that order. Therefore, the last configuration loaded has precedence (and overwrites settings loaded from previous configuration files).

plugin_dir = None

A directory path where plugin code (modules) can be loaded from. By default, this setting is also overridden by the [<app_label>] -> plugin_dir config setting parsed in any of the application configuration files.

If set, this item will be prepended to Meta.plugin_dirs so that a users defined plugin_dir has precedence over others.

In general, this setting should not be defined by the developer, as it is primarily used to allow the end-user to define a plugin_dir without completely trumping the hard-coded list of default plugin_dirs defined by the app/developer.

plugin_dirs = None

A list of directory paths where plugin code (modules) can be loaded from.

Note: Though CementApp.Meta.plugin_dirs is None, Cement will set this to a default list based on CementApp.Meta.label if not set. This will equate to:

['~/.<app_label>/plugins', '/usr/lib/<app_label>/plugins']

Modules are attempted to be loaded in order, and will stop loading once a plugin is successfully loaded from a directory. Therefore this is the oposite of configuration file loading, in that here the first has precedence.

plugin_handler = 'cement'

A handler class that implements the IPlugin interface.

plugins = []

A list of plugins to load. This is generally considered bad practice since plugins should be dynamically enabled/disabled via a plugin config file.

signal_handler(signum, frame)

A function that is called to handle any caught signals.

template_dir = None

A directory path where template files can be loaded from. By default, this setting is also overridden by the [<app_label>] -> template_dir config setting parsed in any of the application configuration files .

If set, this item will be prepended to CementApp.Meta.template_dirs (giving it precedence over other template_dirs.

template_dirs = None

A list of directory paths where template files can be loaded from.

Note: Though CementApp.Meta.template_dirs defaults to None, Cement will set this to a default list based on CementApp.Meta.label. This will equate to:

['~/.<app_label>/templates', '/usr/lib/<app_label>/templates']

Templates are attempted to be loaded in order, and will stop loading once a template is successfully loaded from a directory.

template_module = None

A python package (dotted import path) where template files can be loaded from. This is generally something like myapp.templates where a plugin file would live at myapp/templates/mytemplate.txt. Templates are first loaded from CementApp.Meta.template_dirs, and and secondly from CementApp.Meta.template_module. The template_dirs setting has presedence.

use_backend_globals = True

This is a backward compatibility feature. Cement 2.x.x relies on several global variables hidden in cement.core.backend used for things like storing hooks and handlers. Future versions of Cement will no longer use this mechanism, however in order to maintain backward compatibility this is still the default. By disabling this feature allows multiple instances of CementApp to be created from within the same runtime space without clobbering eachothers hooks/handers/etc.

Be warned that use of third-party extensions might break as they were built using backend globals, and probably have no idea this feature has changed or exists.

CementApp._lay_cement()

Initialize the framework.

CementApp.add_arg(*args, **kw)

A shortcut for self.args.add_argument.

CementApp.add_template_dir(path)

Append a directory path to the list of template directories to parse for templates.

Parameters:path – Directory path that contains template files.

Usage:

app.add_template_dir('/path/to/my/templates')
CementApp.argv

The arguments list that will be used when self.run() is called.

CementApp.catch_signal(signum)

Add signum to the list of signals to catch and handle by Cement.

Parameters:signum – The signal number to catch. See Python signal library.
CementApp.close(code=None)

Close the application. This runs the pre_close and post_close hooks allowing plugins/extensions/etc to cleanup at the end of program execution.

Parameters:code – An exit code to exit with (int), if None is passed then exit with whatever self.exit_code is currently set to. Note: sys.exit() will only be called if CementApp.Meta.exit_on_close==True.
CementApp.debug

Returns boolean based on whether --debug was passed at command line or set via the application’s configuration file.

Returns:boolean
CementApp.extend(member_name, member_object)

Extend the CementApp() object with additional functions/classes such as ‘app.my_custom_function()’, etc. It provides an interface for extensions to provide functionality that travel along with the application object.

Parameters:
  • member_name (str) – The name to attach the object to.
  • member_object – The function or class object to attach to CementApp().
Raises:

cement.core.exc.FrameworkError

CementApp.get_last_rendered()

DEPRECATION WARNING: This function is deprecated as of Cement 2.1.3 in favor of the self.last_rendered property, and will be removed in future versions of Cement.

Return the (data, output_text) tuple of the last time self.render() was called.

Returns:tuple (data, output_text)
CementApp.last_rendered

Return the (data, output_text) tuple of the last time self.render() was called.

Returns:tuple (data, output_text)
CementApp.pargs

Returns the parsed_args object as returned by self.args.parse().

CementApp.reload()

This function is useful for reloading a running applications, for example to reload configuration settings, etc.

Returns:None
CementApp.remove_template_dir(path)

Remove a directory path from the list of template directories to parse for templates.

Parameters:path – Directory path that contains template files.

Usage:

app.remove_template_dir('/path/to/my/templates')
CementApp.render(data, template=None, out=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, **kw)

This is a simple wrapper around self.output.render() which simply returns an empty string if no self.output handler is defined.

Parameters:
  • data – The data dictionary to render.
  • template – The template to render to. Default: None (some output handlers do not use templates).
  • out – A file like object (sys.stdout, or actual file). Set to None is no output is desired (just render and return). Default: sys.stdout
CementApp.run()

This function wraps everything together (after self._setup() is called) to run the application.

Returns:Returns the result of the executed controller function if a base controller is set and a controller function is called, otherwise None if no controller dispatched or no controller function was called.
CementApp.run_forever(interval=1, tb=True)

This function wraps run() with an endless while loop. If any exception is encountered it will be logged and then the application will be reloaded.

Parameters:
  • interval – The number of seconds to sleep before reloading the the appliction.
  • tb – Whether or not to print traceback if exception occurs.
Returns:

It should never return.

CementApp.setup()

This function wraps all ‘_setup’ actons in one call. It is called before self.run(), allowing the application to be _setup but not executed (possibly letting the developer perform other actions before full execution.).

All handlers should be instantiated and callable after setup is complete.

CementApp.validate_config()

Validate application config settings.

Usage:

import os
from cement.core import foundation

class MyApp(foundation.CementApp):
    class Meta:
        label = 'myapp'

    def validate_config(self):
        super(MyApp, self).validate_config()

        # test that the log file directory exist, if not create it
        logdir = os.path.dirname(self.config.get('log', 'file'))

        if not os.path.exists(logdir):
            os.makedirs(logdir)
cement.core.foundation.add_handler_override_options(app)

This is a post_setup hook that adds the handler override options to the argument parser

Parameters:app – The application object.
cement.core.foundation.cement_signal_handler(signum, frame)

Catch a signal, run the ‘signal’ hook, and then raise an exception allowing the app to handle logic elsewhere.

Parameters:
  • signum – The signal number
  • frame – The signal frame.
Raises:

cement.core.exc.CaughtSignal

cement.core.foundation.handler_override(app)

This is a post_argument_parsing hook that overrides a configured handler if defined in CementApp.Meta.handler_override_options and the option is passed at command line with a valid handler label.

Parameters:app – The application object.