Cleo 0.2 is now out with a lot of improvements and new features.

What is cleo?

Cleo eases the creation of beautiful and testable command line interfaces.

It is heavily inspired by the Symfony Console Component, with some useful additions.

Full documentation available here:


You can install Cleo in two different ways:


The Application object manages the CLI application:

from cleo import Application

console = Application()

The run() method parses the arguments and options passed on the command line and executes the right command.

Registering a new command can easily be done via the register() method, which returns a Command instance:

from cleo.input import InputArgument, InputOption

def hello(input_, output_):
    name = input_.get_argument('name')

    output_.writeln('Hello <info>%s</info>' % name)

        InputArgument('name', InputArgument.REQUIRED, 'The name'),
    .set_description('Says hello!')\

You can also register new commands via classes.

from cleo import Command

class HelloCommand(Command):

    def configure(self):
            .set_description('Says hello!')\
            .add_argument('name', InputArgument.REQUIRED, 'The name')

    def execute(input_, output_):
        name = input_.get_argument('name')

        output_.writeln('Hello <info>%s</info>' % name)


But it might be a little too verbose for some. That's why commands can also be declared and registered via dictionaries.

hello_command = {
    'name': 'hello',
    'description': 'Says hello!',
    'arguments': [
        'name': {
            'mode': 'required',
            'description': 'The name'
    'code': hello


With dictionaries, you will not be able to do as many things as with classes declaration since you won't have access to the Command instance.

Output coloring

Cleo provides output coloring out of the box, you just need to surround the text with tags:

# green text

# yellow text

# black text on a cyan background

# white text on a red background

Those are the default styles but you can easily define your own :

style = OutputFormatterStyle('red', 'yellow', ['bold', 'blink'])
output_.get_formatter().set_style('fire', style)

If you don't want to set the styles upfront, you can just as easily set the colors and options inside the tagnames :

# green text

# black text on a cyan background

# bold text on a yellow background

Testable commands

Cleo provides input and output abstraction so that you can easily unit-test your commands, especially with the CommandTester class:

from unittest import TestCase
from cleo import Application, CommandTester

class GreetCommandTest(TestCase):

    def test_execute(self):
        application = Application()
        # Or application.add(GreetCommand()) if using classes

        commmand = application.find('demo:greet')
        command_tester = CommandTester(command)
        command_tester.execute([('command', command.get_name())])

        self.assertRegex('...', command_tester.get_display())

        # ...

Basically, the get_display() method returns what would have been displayed during a normal call from the console.


Cleo comes bundled with some nice helpers that will cover some basic needs when developing command-line interfaces.

The DialogHelper will, basically, prompt the user for answers:

# ...
if dialog.ask_confirmation(
    '<question>Continue with this action?</question>',
    # Some code

This code will prompt for a yes/no anwser, while this code:

# ...
name = dialog.ask(
    'Please enter your name',
    'John Doe'

will prompt for a more generic answer.

The ProgressHelper allows you to display a progress bar for actions that might take a while:

progress = self.get_helper_set().get('progress')

progress.start(output_, 50)

for _ in range(50)
    # ... do some work

    # advance the progress bar 1 unit


And the TableHelper will display automatically tabular data:

table = app.get_helper_set().get('table')
table.set_headers(['ISBN', 'Title', 'Author'])
   ['99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'],
   ['9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'],
   ['960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'],
   ['80-902734-1-6', 'And Then There Were None', 'Agatha Christie']


There is a lot more you can do with Cleo, you can just give a look at the documentation:

And if you are interested by how it all works, you can just check out the Github Repository, and feel free to contribute.

And, finally, here are some features for the 0.3 version:

  • Set commands with decorators
  • Validators for the arguments and options
  • Autocompletion of commands

You can check the advancement on the Github project

Sébastien Eustace

Sébastien Eustace

Born & raised in France, and currently living in the beautiful city of Quito, Ecuador, I'm a software engineer, proud pythonista (but knowledgeable in other languages and technologies as well) but overall an open source lover.

View Comments