docopt for dummies

Parsing command line arguments is an annoying piece of boilerplate we all have to do. Documenting our code is either an absolutely essential part of software engineering, or a frivolous waste of research time, depending on who you ask. But what if I told you that we can combine the two? That you can handle your argument parsing simply by documenting how your code works? Well, the dream is now reality.

docopt is a neat tool for building command line interfaces from help messages. Want to add an option or argument to your script? Don’t want to add yet another line of argparse boilerplate? Just add the option to your module docstring (you did write docstring, didn’t you?) and docopt takes care of the rest. Here we take a look at docopt for Python, but it’s implemented in many different languages. There’s a repository for each supported language on github, so check it out!

"""Remind lazy programmers to document their code.

Usage:
    remind.py [-hv] [--eternal | --n_reminders=<n>] <name>

Arguments:
    name    Somebody who needs to be reminded to document their code

Options:
    -h --help            show this message and exit.
    --version            show version information and exit.
    -v --verbose         show unnecessary extra information.
    --eternal            give reminders forever.
    --n_reminders=<n>    number of reminders to give. [default: 5]
"""

from docopt import docopt

def main():

    # docopt saves arguments and options as key:value pairs in a dictionary
    args = docopt(__doc__, version='0.1')

    verbose = args['--verbose']
    name = args['<name>']

    if verbose:
        print('You are about to be reminded to document your code')

    # do the thing
    if args['--eternal']:
        if verbose:
            print('This may take a while...')
        while True:
            print(f'Document your code, {name}!')
    else:
        for _ in range(int(args['--n_reminders'])):
            print(f'Document your code, {name}')

    if verbose:
        print('You have been reminded to document your code')
        
if __name__=='__main__':
    main()

And that’s it! Never again will you have to give up the start of your script to adding all your options to argparse. Pass a docstring to docopt and it will build a command line interface for you then parse the command line argument vector to extract your arguments and options. Options and optional arguments are enclosed in “[ ]” brackets, while variable names are either enclosed in “< >” chevrons or written in CAPS. Default values for options can be specified in “[ ]” brackets in the list of options. A single usage example containing positional arguments is all that’s needed – if you have lots of options and don’t want to write multiple usage examples, just stick ‘[options]’ in your usage example and leave it there. The syntax is powerful yet flexible, and has been built around the conventions used in help messages and man pages over the last several decades, so chances are if you already have a docstring (and you do, don’t you?) it’ll be easy to feed to docopt. If you don’t, now you can take the time you would normally waste parsing command line arguments and spend it documenting your code instead!

Author