Color your outputs with Python

26th of October, 2013 Programming Python

Contents

Something nice

I am coding in Python very often for producing scripts quickly or for bigger projects. In the latter case, I like to have something nice to display. I attach a great importance to the messages I print for debugging, information or help. But sometimes the outputs I have are very long in a terminal and then it becomes interesting to color them for clarity. I will give here the procedure I use to add some colors in my terminal with Python. This is maybe not the best way and definitely not the only way. You can find other tutorials about this.

Give me some packets

I am using two packets; colorama and termcolor. The first one gives the possibility to easily use colors on a terminal for Linux, Mac and Windows. Indeed managing the ANSI escape sequences with all the different platforms can be a painful task. The last package gives some functions to quickly manage text colors, highlights and attributes.

The installation of these packages is straightforward and the same for both of them.

With code it is better

Imports

Now comes the coding part. Before giving any examples, it is necessary to include the packages inside the scripts where we want to color the outputs.

import sys
try:
    from colorama import init
    from colorama import Back
    from colorama import Fore
    from colorama import Style
    from termcolor import colored
    from termcolor import cprint
    init()
except ImportError:
    print "Make sure you have installed the 'colorama', 'termcolor' packages."

The easy way

The easiest method to use colors is to play only with colorama. It suffices to define the foreground, the background, the style, the text to print and reset everything to go back to the default printing of the terminal.

print(Back.WHITE + Fore.BLUE + Style.DIM + "Some blue text with a white background" + Style.RESET_ALL)

It is possible to output the same result with termcolor lazily by using the cprint() function. In my opinion, it is a better way because it is more intuitive but the understanding of the ANSI escape sequences is more implicit.

cprint("Some blue text with a white background", 'blue', 'on_white')

Let is go a bit further by adding an argument and a file descriptor. It can be a powerful tool to log errors or to specify exactly where we want to print the outputs.

cprint("Some bold red text with a yellow background printed on stderr",
       'red', 'on_yellow', attrs = ['bold'], file = sys.stderr)

Colored might be cool

Still playing with termcolor, I prefer to use the colored() function because there is the possibility to store the text formatted for being colored in a variable. For instance you can try:

mytext = colored('Hello world!', 'blue', attrs = ['reverse', 'concealed'])
print mytext

It will print Hello world! on a blue background and we could be able to reuse the variable mytext again which can be very handy. Of course you can use the colored() function like this:

print(colored('Hello, World!', 'blue', attrs = ['reverse', 'concealed']))

Go building

A simple printer

So now that we have seen the main possibilities offered by the packages, it is time to create our own functions. It can also be useful for bigger projects to create Classes and with specific Objects to print things. In this post, I will just show a simple function that can give you some ways to go further.

So let is say I want to print a text and have the possibility to select or not if the output will be printed in bold. I will create a function that can handle the colors and the bold attribute as shown below:

def myprinter(arg_text, arg_color, **arg_attrs):
    """Handles colors and the 'Bold' attribute for colored outputs.

    Args:
        arg_text: The text that will be printed.
        arg_color: The color used for the output.
        **arg_attrs: Optional attributes.
    """

    att_bold = "b"          # The 'Bold' attribute
    color = ""              # Empty variable that stores a color

    clr_b_val = 'blue'      # Blue: value
    clr_c_val = 'cyan'      # Cyan: value
    clr_g_val = 'green'     # Green: value
    clr_m_val = 'magenta'   # Magenta: value
    clr_r_val = 'red'       # Red: value
    clr_w_val = 'white'     # White: value
    clr_y_val = 'yellow'    # Yellow: value
    clr_b_key = 'b'         # Blue: key
    clr_c_key = 'c'         # Cyan: key
    clr_g_key = 'g'         # Green: key
    clr_m_key = 'm'         # Magenta: key
    clr_r_key = 'r'         # Red: key
    clr_w_key = 'w'         # White: key
    clr_y_key = 'y'         # Yellow: key

    # Blue
    if (arg_color == clr_b_key):
        color = clr_b_val
    # Cyan
    elif (arg_color == clr_c_key):
        color = clr_c_val
    # Green
    elif (arg_color == clr_g_key):
        color = clr_g_val
    # Magenta
    elif (arg_color == clr_m_key):
        color = clr_m_val
    # Red
    elif (arg_color == clr_r_key):
        color = clr_r_val
    # White
    elif (arg_color == clr_w_key):
        color = clr_w_val
    # Yellow 
    elif (arg_color == clr_y_key):
        color = clr_y_val

    # Attribute: Bold
    if (att_bold in arg_attrs):
        print(colored("%s" % arg_text, color, attrs = ["bold"]))
    # Attribute: None
    else:
        print(colored("%s" % arg_text, color))

Simple, do not you think? So what is happening here? Basically, the function requires two parameters; the text to print and the color to use. The first part of the function is just creating shortcuts for the colors. In other words, instead of typing magenta it suffices to type m. It is a personal choice to write faster. For instance, if I want to print the string "Hello world!" in yellow, I will simply type:

myprinter("Hello world!", 'y')

The second part of the function is related to the **arg_attrs which is an optional parameter. With the att_bold variable, we define that we call the bold attribute if we type b='yes' when using the myprinter() function. If we continue with our previous string "Hello world!" and we want to print it using bold this time, we just need to type:

myprinter("Hello world!", 'y', b='yes')

Just imagine

I gave here only one example and a very simple one. Indeed only the bold attribute was handled. It is obviously possible to create different functions for other purposes. For instance in my case, I like to create a Printer class and I usually define some skeletons for my outputs; one for an information, another one for errors, another one for alerts, and so on. You can find a real example of this in the source code of my project ReporTeX.

Things can become very interesting if you decide to combine colored outputs with logging. Also have a look on the documentations of colorama and termcolor; they are very well written and present other utilization cases that might be useful for your own projects.