Multiple Stacked Controllers¶
from cement.core.foundation import CementApp
from cement.core.controller import CementBaseController, expose
# define application controllers
class MyAppBaseController(CementBaseController):
class Meta:
label = 'base'
description = "my application does amazing things"
arguments = [
(['--base-opt'], dict(help="option under base controller")),
]
@expose(help="base controller default command", hide=True)
def default(self):
print "Inside MyAppBaseController.default()"
@expose(help="another base controller command")
def command1(self):
print "Inside MyAppBaseController.command1()"
class SecondController(CementBaseController):
class Meta:
label = 'second_controller'
stacked_on = 'base'
stacked_type = 'nested'
description = "this is the second controller (stacked/nested on base)"
arguments = [
(['--2nd-opt'], dict(help="another option under base controller")),
]
@expose(help="second-controller default command", hide=True)
def default(self):
print "Inside SecondController.default()"
@expose(help="this is a command under the second-controller namespace")
def command2(self):
print "Inside SecondController.command2()"
class ThirdController(CementBaseController):
class Meta:
label = 'third_controller'
stacked_on = 'second_controller'
stacked_type = 'embedded'
description = "this controller is embedded in the second-controller"
arguments = [
(['--3rd-opt'], dict(help="an option only under 3rd controller")),
]
@expose(help="another command under the second-controller namespace")
def command3(self):
print "Inside ThirdController.command3()"
class FourthController(CementBaseController):
class Meta:
label = 'fourth_controller'
stacked_on = 'second_controller'
stacked_type = 'nested'
description = "this controller is nested on the second-controller"
arguments = [
(['--4th-opt'], dict(help="an option only under 3rd controller")),
]
@expose(help="a command only under the fourth-controller namespace")
def command4(self):
print "Inside FourthController.command4()"
class MyApp(CementApp):
class Meta:
label = 'myapp'
handlers = [
MyAppBaseController,
SecondController,
ThirdController,
FourthController,
]
def main():
with MyApp() as app:
app.run()
if __name__ == '__main__':
main()
In the base controller output of –help notice that the second-controller is listed as a sub-command:
$ python myapp.py --help
usage: myapp.py (sub-commands ...) [options ...] {arguments ...}
my application does amazing things
commands:
command1
another base controller command
second-controller
this is the second controller (stacked/nested on base)
optional arguments:
-h, --help show this help message and exit
--debug toggle debug output
--quiet suppress all output
--base-opt BASE_OPT option under base controller
$ python myapp.py
Inside MyAppBaseController.default()
$ python myapp.py command1
Inside MyAppBaseController.command1()
$ python myapp.py second-controller
Inside SecondController.default()
$ python myapp.py second-controller --help
usage: myapp.py (sub-commands ...) [options ...] {arguments ...}
this is the second controller (stacked/nested on base)
commands:
command2
this is a command under the second-controller namespace
command3
another command under the second-controller namespace
fourth-controller
this controller is nested on the second-controller
optional arguments:
-h, --help show this help message and exit
--debug toggle debug output
--quiet suppress all output
--2nd-opt 2ND_OPT another option under base controller
--3rd-opt 3RD_OPT an option only under 3rd controller
Under the second-controller you can see the commands and options from the second and third controllers. In this example, the second-controller is nested on the base controller, and the third-controller is embedded on the second-controller. Finally, we see that the fourth-controller is also nested on the second-controller creating a sub-sub-command.
$ python myapp.py second-controller command3
Inside ThirdController.command3()
$ python myapp.py second-controller fourth-controller --help
usage: myapp.py (sub-commands ...) [options ...] {arguments ...}
this controller is nested on the second-controller
commands:
command4
a command only under the fourth-controller namespace
optional arguments:
-h, --help show this help message and exit
--debug toggle debug output
--quiet suppress all output
--4th-opt 4TH_OPT an option only under 3rd controller
$ python myapp.py second-controller fourth-controller command4
Inside FourthController.command4()