Abstract Base Controllers for Shared Arguments and Commands

For larger, complex applications it is often very useful to have abstract base controllers that hold shared arguments and commands that a number of other controllers have in common. Note that in the example below, you can not override the Meta.arguments in a sub-class or you overwrite the shared arguments, but it is possible to append to them in order to maintain the defaults while having unique options/arguments for the sub-classed controller. As well, you can add any number of additional commands in the sub-class but still maintain the existing shared commands (or override them as necessary).

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

class AbstractBaseController(CementBaseController):
    This is an abstract base class that is useless on its own, but used
    by other classes to sub-class from and to share common commands and
    arguments.  This should not be confused with the `MyAppBaseController`
    used as the ``base_controller`` namespace.

    class Meta:
        stacked_on = 'base'
        stacked_type = 'nested'
        arguments = [
            ( ['-f', '--foo'], dict(help='notorious foo option')),

    def _setup(self, base_app):
        super(AbstractBaseController, self)._setup(base_app)

        # add a common object that will be used in any sub-class
        self.reusable_dict = dict()

    def default(self):
        This command will be shared within all controllers that sub-class
        from here.  It can also be overridden in the sub-class, but for
        this example we are making it dynamic.

        # do something with self.my_shared_obj here?
        if 'some_key' in self.reusable_dict.keys():

        # or do something with parsed args?
        if self.app.pargs.foo:
            print "Foo option was passed with value: %s" % self.app.pargs.foo

        # or maybe do something dynamically
        print("Inside %s.default()" % self.__class__.__name__)

class MyAppBaseController(CementBaseController):
    This is the application base controller, but we don't want to use our
    abstract base class here.

    class Meta:
        label = 'base'

    def default(self):
        print("Inside MyAppBaseController.default()")

class Controller1(AbstractBaseController):
    This controller sub-classes from the abstract base class as to inherite
    shared arguments, and commands.

    class Meta:
        label = 'controller1'

    def command1(self):
        print("Inside Controller1.command1()")

class Controller2(AbstractBaseController):
    This controller also sub-classes from the abstract base class as to
    inherite shared arguments, and commands.

    class Meta:
        label = 'controller2'

    def command2(self):
        print("Inside Controller2.command2()")

class MyApp(CementApp):
    class Meta:
        label = 'myapp'
        base_controller = 'base'
        handlers = [

def main():
    with MyApp() as app:

if __name__ == '__main__':


$ python myapp.py
Inside MyAppBaseController.default()

$ python myapp.py --help
usage: myapp.py (sub-commands ...) [options ...] {arguments ...}

Base Controller


    Controller1 Controller

    Controller2 Controller

optional arguments:
  -h, --help  show this help message and exit
  --debug     toggle debug output
  --quiet     suppress all output

$ python myapp.py controller1
Inside Controller1.default()

$ python myapp.py controller1 --foo=bar
Foo option was passed with value: bar
Inside Controller1.default()

$ python myapp.py controller2
Inside Controller2.default()