cement.core.foundation
Cement core foundation module.
- class cement.core.foundation.App(label: str | None = None, **kw: Any)[source]
Bases:
MetaMixin
The primary application object class.
- class Meta[source]
Bases:
object
Application meta-data (can also be passed as keyword arguments to the parent class).
- alternative_module_mapping: Dict[str, str] = {}
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
App.__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 ofjson
, 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.
- Type:
EXPERIMENTAL FEATURE
- argument_handler = 'argparse'
A handler class that implements the Argument interface.
- argv: list[str] = None
A list of arguments to use for parsing command line arguments and options.
Note: Though
App.Meta.argv
defaults toNone
, Cement will set this tolist(sys.argv[1:])
if no argv is set in Meta duringsetup()
.
- bootstrap: str | None = 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 aload()
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 hard-coded application code. It is also called before plugins are loaded.
- catch_signals = [Signals.SIGTERM, Signals.SIGINT, Signals.SIGHUP]
List of signals to catch, and raise
cement.core.exc.CaughtSignal
for. Can be set toNone
to disable signal handling.
- config_dirs: list[str] = None
List of config directories to search config files (appended to the builtin list of directories defined by Cement). For each directory cement will load all files that ends with
.conf
. Note: ThoughApp.Meta.config_dirs
defaults toNone
, Cement will set this to a default list based onApp.Meta.label
(or in other words, the name of the application). This will equate to:[ '/etc/myapp/ext.d/', '/etc/myapp/plugins.d/', '~/.myapp/config/ext.d/', '~/.myapp/config/plugins.d/', ]
Directories and files inside are loaded in order, and have precedence in order. Therefore, the last configuration loaded has precedence (and overwrites settings loaded from previous configuration files). These configuration will be overriden by configuration from
CementApp.Meta.config_files
.Note that
.conf
is the default config file extension, defined byCementApp.Meta.config_file_suffix
.
- config_file_suffix = '.conf'
Extension used to identify application and plugin configuration files.
- config_files: list[str] = None
List of config files to parse (appended to the builtin list of config files defined by Cement).
Note: Though
App.Meta.config_files
defaults toNone
, Cement will set this to a default list based onApp.Meta.label
(or in other words, the name of the application). This will equate to:[ '/etc/myapp/myapp.conf', '~/.config/myapp/myapp.conf', '~/.myapp.conf', ]
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 byApp.Meta.config_file_suffix
.
- config_handler = 'configparser'
A handler class that implements the Config interface.
- config_section: str = None
The base configuration section for the application.
Note: Though
App.Meta.config_section
defaults toNone
, Cement will set this to the value ofApp.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
App.Meta.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 might not need/wantLoggingLogHandler
to be registered).
- core_handler_override_options: _choo_type = {'output': (['-o'], {'help': 'output handler'})}
Similar to
App.Meta.handler_override_options
but these are the core defaults required by Cement. This dictionary can be overridden byApp.Meta.handler_override_options
(when they are merged together).
- core_interfaces: List[Type[Interface]] = [<class 'cement.core.extension.ExtensionInterface'>, <class 'cement.core.log.LogInterface'>, <class 'cement.core.config.ConfigInterface'>, <class 'cement.core.mail.MailInterface'>, <class 'cement.core.plugin.PluginInterface'>, <class 'cement.core.output.OutputInterface'>, <class 'cement.core.template.TemplateInterface'>, <class 'cement.core.arg.ArgumentInterface'>, <class 'cement.core.controller.ControllerInterface'>, <class 'cement.core.cache.CacheInterface'>]
List of core interfaces to be defined (by the framework). You should not modify this unless you really know what you’re doing… instead, you probably want to add your own interfaces to
App.Meta.interfaces
.
- core_meta_override = ['debug', 'plugin_dir', 'ignore_deprecation_warnings', 'template_dir', 'mail_handler', 'cache_handler', 'log_handler', 'output_handler', 'template_handler']
List of meta options that can/will be overridden by config options of the
base
config section (wherebase
is the base configuration section of the application which is determined byApp.Meta.config_section
but defaults toApp.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 you should useApp.Meta.meta_override
.
- core_system_config_dirs = ['/etc/{label}/ext.d', '/etc/{label}/plugins.d']
List of builtin system level configuration directories to scan for config files.
- core_system_config_files = ['/etc/{label}/{label}{suffix}']
List of builtin system level configuration files.
- core_system_plugin_dirs = ['/usr/lib/{label}/plugins']
List of builtin system level directories to scan for plugins.
- core_system_template_dirs = ['/usr/lib/{label}/templates']
List of builtin system level directories to scan for templates.
- core_user_config_dirs = ['{home_dir}/.config/{label}/ext.d', '{home_dir}/.config/{label}/plugins.d', '{home_dir}/.{label}/config/ext.d', '{home_dir}/.{label}/config/plugins.d']
List of builtin user level configuration directories to scan for config files.
- core_user_config_files = ['{home_dir}/.config/{label}/{label}{suffix}', '{home_dir}/.{label}/config/{label}{suffix}', '{home_dir}/.{label}{suffix}']
List of builtin user level configuration files.
- core_user_plugin_dirs = ['{home_dir}/.config/{label}/plugins', '{home_dir}/.{label}/plugins']
List of builtin user level directories to scan for plugins.
- core_user_template_dirs = ['{home_dir}/.config/{label}/templates', '{home_dir}/.{label}/templates']
List of builtin user level template directories to scan for templates.
- debug = False
This is set to
True
if any of thedebug_argument_options
are passed at command line. Useful for debugging.
- debug_argument_help = 'full application debug mode'
The debug argument help text that is displayed in
--help
.
- debug_argument_options = ['-d', '--debug']
The argument option(s) to toggle debug mode via cli. Set to None to remove these options from the app.
- define_hooks: List[str] = []
List of hook definitions (labels). 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()
whenclose()
is called. The default isFalse
, however ifTrue
then the app will callsys.exit(X)
whereX
isself.exit_code
.
- extension_handler = 'cement'
A handler class that implements the Extension interface.
- framework_logging = True
This setting is deprecated and will be changed or removed in Cement v3.2.0. See: https://docs.builtoncement.com/release-information/deprecations#3.0.8-2
Whether or not to enable Cement framework logging if
--debug
is passed at the command line. 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_LOG. Therefore, if in production you do not want the Cement framework log enabled (when the
debug
option is passed at command line), you can set this option toFalse
. SettingCEMENT_LOG=1
in the environment will trigger this setting toTrue
.
- handler_override_options: Dict[str, ArgparseArgumentType] = {}
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
App.Meta.core_handler_override_options
but this one has precedence.Dictionary Format:
<interface_name> = (option_arguments, help_text)
See
App.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 theApp.Meta.core_meta_override_options
will be ignore (not recommended as some extensions rely on this feature).
- handlers: List[Type[Handler]] = []
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[Tuple[str, Callable]] = []
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.
- interfaces: List[Type[Interface]] = []
List of interfaces to be defined. Must be a list of uninstantiated interface base classes.
I.e.
[MyCustomInterface, SomeOtherInterface]
- label: str = 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
, ormy-awesome-app
.
- log_handler = 'logging'
A handler class that implements the Log interface.
- mail_handler = 'dummy'
A handler class that implements the Mail interface.
- meta_defaults: Dict[str, Any] = {}
Default meta-data 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 overrideJsonOutputHandler.Meta.json_module
withujson
by doing the following:from cement import App META = { 'output.json': { 'json_module': 'ujson', } } class MyApp(App): class Meta: label = 'myapp' extensions = ['json'] meta_defaults = META
- meta_override: List[str] = []
List of meta options that can/will be overridden by config options of the
base
config section (wherebase
is the base configuration section of the application which is determined byApp.Meta.config_section
but defaults toApp.Meta.label
).
- output_handler = 'dummy'
A handler class that implements the Output interface.
- plugin_dir: str | None = None
A directory path where plugin code (modules) can be loaded from. By default, this setting is also overridden by the
myapp.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 definedplugin_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 defaultplugin_dirs
defined by the app/developer.
- plugin_dirs: list[str] = None
A list of directory paths where plugin code (modules) can be loaded from (appended to the builtin list of directories defined by Cement).
Note: Though
App.Meta.plugin_dirs
defaults toNone
, Cement will populate this with a default list based onApp.Meta.label
. This will equate to:[ '~/.myapp/plugins', '~/.config/myapp/plugins', '/usr/lib/myapp/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 Plugin interface.
- plugin_module: str = 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 atmyapp/plugins/myplugin.py
ormyapp/plugins/myplugin/
(directory). 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.
- plugins: list[str] = []
A list of plugins to load. This is generally considered bad practice since plugins should be dynamically enabled/disabled via a plugin config file.
- quiet = False
Suppress all console output (print/log/render). This is set to
True
if any of thequiet_argument_options
are passed at command line.
- quiet_argument_help = 'suppress all console output'
The quiet argument help text that is displayed in
--help
.
- quiet_argument_options = ['-q', '--quiet']
The argument option(s) to toggle quiet mode via cli. Set to None to remove these options from the app.
- signal_handler(frame: FrameType | None) Any
A function that is called to handle any caught signals.
- template_dir: str | None = None
A directory path where template files can be loaded from. By default, this setting is also overridden by the
myapp.template_dir
config setting parsed in any of the application configuration files .If set, this item will be prepended to
App.Meta.template_dirs
(giving it precedence over othertemplate_dirs
.
- template_dirs: List[str] = None
A list of directory paths where template files can be loaded from (appended to the builtin list of directories defined by Cement).
Note: Though
App.Meta.template_dirs
defaults toNone
, Cement will populate this with a default list based onApp.Meta.label
. This will equate to:[ '~/.myapp/templates', '~/.config/myapp/templates', '/usr/lib/myapp/templates', ]
Templates are attempted to be loaded in order, and will stop loading once a template is successfully loaded from a directory.
- template_handler = 'dummy'
A handler class that implements the Template interface.
- template_module: str | None = 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 atmyapp/templates/mytemplate.txt
. Templates are first loaded fromApp.Meta.template_dirs
, and and secondly fromApp.Meta.template_module
. Thetemplate_dirs
setting has presedence.
- add_config_dir(path: str) None [source]
Append a directory
path
to the list of directories to parse for config files.- Parameters:
path (str) – Directory path that contains config files.
Example:
app.add_config_dir('/path/to/my/config/')
- add_config_file(path: str) None [source]
Append a file
path
to the list of configuration files to parse.- Parameters:
path (str) – Configuration file path..
Example:
app.add_config_file('/path/to/my/config/file')
- add_plugin_dir(path: str) None [source]
Append a directory
path
to the list of directories to scan for plugins.- Parameters:
path (str) – Directory path that contains plugin files.
Example:
app.add_plugin_dir('/path/to/my/plugins')
- add_template_dir(path: str) None [source]
Append a directory
path
to the list of template directories to parse for templates.- Parameters:
path (str) – Directory path that contains template files.
Example:
app.add_template_dir('/path/to/my/templates')
- catch_signal(signum: int) None [source]
Add
signum
to the list of signals to catch and handle by Cement.- Parameters:
signum (int) – The signal number to catch. See Python
signal library
.
- close(code: int | None = None) None [source]
Close the application. This runs the
pre_close
andpost_close
hooks allowing plugins/extensions/etc to cleanup at the end of program execution.- Parameters:
code – An exit code to exit with (
int
), ifNone
isset (passed then exit with whatever self.exit_code is currently)
Note (to.) –
sys.exit()
will only be called ifApp.Meta.exit_on_close==True.
- extend(member_name: str, member_object: Any) None [source]
Extend the
App()
object with additional functions/classes such asapp.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
App().
- Raises:
cement.core.exc.FrameworkError – If
App().member_name
already exists.
- property last_rendered: Tuple[Dict[str, Any], str | None] | None
Return the
(data, output_text)
tuple of the last timeself.render()
was called.- Returns:
(data, output_text)
- Return type:
- reload() None [source]
This function is useful for reloading a running applications, for example to reload configuration settings, etc.
- remove_template_dir(path: str) None [source]
Remove a directory
path
from the list of template directories to parse for templates.- Parameters:
path (str) – Directory path that contains template files.
Example
app.remove_template_dir('/path/to/my/templates')
- render(data: ~typing.Any, template: str | None = None, out: ~typing.IO = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, handler: str | None = None, **kw: ~typing.Any) str [source]
This is a simple wrapper around
self.output.render()
which simply returns an empty string if no output handler is defined.- Parameters:
- Keyword Arguments:
template (str) – The template to render to (note that some output handlers do not use templates).
out – A file like object (i.e.
sys.stdout
, or actual file). Set toNone
if no output is desired (just render and return). Default issys.stdout
, however ifApp.quiet
isTrue
, this will be set toNone
.handler – The output handler to use to render. Defaults to
App.Meta.output_handler
.
- run() None | Any [source]
This function wraps everything together (after
self._setup()
is called) to run the application.- 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.- Return type:
unknown
- run_forever(interval: int = 1, tb: bool = True) None [source]
This function wraps
self.run()
with an endless while loop. If any exception is encountered it will be logged and then the application will be reloaded.
- setup() None [source]
This function wraps all
_setup
actons in one call. It is called beforeself.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.
- validate_config() None [source]
Validate application config settings.
Example:
import os from cement import App class MyApp(App): 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)
- class cement.core.foundation.TestApp(label: str | None = None, **kw: Any)[source]
Bases:
App
App subclass useful for testing.
- cement.core.foundation.add_handler_override_options(app: App) None [source]
This is a
post_setup
hook that adds the handler override options to the argument parser- Parameters:
app (instance) – The application object
- cement.core.foundation.cement_signal_handler(signum: int, frame: FrameType | None) Any [source]
Catch a signal, run the
signal
hook, and then raise an exception allowing the app to handle logic elsewhere.- Parameters:
signum (int) – The signal number
frame – The signal frame
- Raises:
cement.core.exc.CaughtSignal – Raised, passing
signum
, andframe
- cement.core.foundation.handler_override(app: App) None [source]
This is a
post_argument_parsing
hook that overrides a configured handler if defined inApp.Meta.handler_override_options
and the option is passed at command line with a valid handler label.- Parameters:
app (instance) – The application object.