Framework Extensions

Cement defines an extension interface called IExtension, as well as the default CementExtensionHandler that implements the interface. Its purpose is to manage loading framework extensions and making them usable by the application. Extensions are similar to Application Plugins, but at the framework level.

Please note that there may be other handler’s that implement the IExtension interface. The documentation below only references usage based on the interface and not the full capabilities of the implementation.

The following extension handlers are included and maintained with Cement2:

Please reference the IExtension interface documentation for writing your own extension handler.

Extension Configuration Settings

The following Meta settings are honored under the CementApp:

extension_handler
A handler class that implements the IExtension interface. This can be a string (label of a registered handler), an uninstantiated class, or an instantiated class object. Default: CementExtensionHandler.
core_extensions
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).
extensions
List of additional framework extensions to load. Default: []

The following example shows how to alter these settings for your application:

from cement2.core import foundation

try:
    app = foundation.CementApp('myapp',
        extension_handler = MyExtensionHandler
        core_extensions = [
            'cement_output',
            'cement_plugin',
            'configparser',
            'logging',
            'argparse',
            ]
        extensions = ['myapp.ext.ext_something_fansy']
        )
    app.setup()
    app.run()
finally:
    app.close()

Creating an Extension

The extension system is a mechanism for dynamically loading code to extend the functionality of the framework. In general, this includes the registration of interfaces, handlers, and/or hooks.

The following is an example extension that provides an Output Handler. We will assume this extension is part of our ‘myapp’ application, so the extension module would be ‘myapp.ext.ext_myapp_output’ (or whatever you want to call it).

from cement2.core import backend, handler, output

Log = backend.minimal_logger(__name__)

class MyAppOutputHandler(object):
    class Meta:
        interface = output.IOutput
        label = 'myapp_output'

    def __init__(self):
        self.app = None

    def setup(self, app_obj):
        self.app = app_obj

    def render(self, data_dict, template=None):
        Log.debug("Rendering output via MyAppOutputHandler")
        for key in data_dict.keys():
            print "%s => %s" % (key, data_dict[key])

handler.register(MyAppOutputHandler)

Take note of two things. One is, the ‘Log’ we are using is from cement2.core.backend.minimal_logger(__name__). Framework extensions do not use the application log handler, ever. Use the minimal_logger(), and only log to ‘DEBUG’ (recommended).

Secondly, in our extension file we need to define any interfaces, register handlers and/or hooks if necessary. In this example we only needed to register our output handler (which happens when the extension is loaded by the application).

You will notice that extensions are essentially the same as application plugins, however the difference is both when the code is loaded, as well as the purpose of that code. Framework extensions add functionality to the framework for the application to utilize, where application plugins extend the functionality of the application.

Loading an Extension

Extensions are loaded when ‘setup()’ is called on an application. Cement automatically loads all extensions listed under the applications ‘core_extensions’ and ‘extensions’ meta options.

To load the above example into our application, we just add it to the list of extensions (not core extensions). Lets assume the extension code lives in ‘myapp/ext/ext_something_fansy.py’:

from cement2.core import foundation

try:
    app = foundation.CementApp('myapp',
        extensions = ['myapp.ext.ext_something_fansy']
        )
    app.setup()
    app.run()
finally:
    app.close()

Project Versions

Table Of Contents

Previous topic

Interfaces and Handlers

Next topic

Configuration Handling

This Page