Docopt in Python

Stop wasting your time parsing argument vectors!

$ python argparse_action.py -h

usage: argparse_action.py [-h] [-s SIMPLE_VALUE] [-c] [-t] [-f]
                          [-a COLLECTION] [-A] [-B] [--version]

optional arguments:
  -h, --help       show this help message and exit
  -s SIMPLE_VALUE  Store a simple value
  -c               Store a constant value
  -t               Set a switch to true
  -f               Set a switch to false
  -a COLLECTION    Add repeated values to a list
  -A               Add different values to list
  -B               Add different values to list
  --version        show program's version number and exit

Problem: Solved!

  • We have optparse, argparse in the standard library and Niko did a great lightning talk about it
  • We have click, which is really nice and i like it
  • We have frameworks like cliff which uses dynamic code loading, formatter classes, an interactive mode, ...
  • We have code which is able to parse your code to auto-generate command line interface like clime

Problem: Solved! in style?

Style: Make hard things look effortless

Usage:
  quick_example.py tcp <host> <port> [--timeout=<seconds>]
  quick_example.py serial <port> [--baud=9600] [--timeout=<seconds>]
  quick_example.py -h | --help | --version

Can you read & understand this?

Yes?

Turns out:

This is a POSIX spec!

  • Have a look at the POSIX specs
    • Hint: They think HTML-frames are a good idea,
      so click on chapter 12 in the lower left or visit this page
  • You are using this on UNIXoid systems for years!
  • The "Usage: ..." syntax is actually a formal standard and that means: Parsers can be auto-generated!

 

Docopt uses the syntax specs to generate a parser
based on a simple docstring you write!

With docopt you write:

"""Usage:
  quick_example.py tcp <host> <port> [--timeout=<seconds>]
  quick_example.py serial <port> [--baud=9600] [--timeout=<seconds>]
  quick_example.py -h | --help | --version

"""
from docopt import docopt
if __name__ == '__main__':
    arguments = docopt(__doc__, version='0.1.1rc')
    print(arguments)  # print a dict() with our arguments

Some facts to think about

  • You can easily outline the features for your command line tool by writing the --help for it
  • Docopt returns a single dictionary, plain and simple
    • Easy to merge options from config files (configparser) or check their datatypes (schema)
  • Docopt follows the DRY principle (don't repeat yourself)
  • Docopt is implemented in many languages: Just learn it once and use it everywhere else
    • docopt.py is only 473 LOC

Problem: Solved! (20% more cool)

http://docopt.org​

(watch the great video for more detail and play around)

Live-Demos

~/Development/Python/docopt-demo​

DocOptopus

By Stefan Antoni

DocOptopus

A quick introduction in docopt.

  • 2,176