Using Docopt in python, the most user-friendly command-line parsing library | by Jonathan Leban | Towards Data Science

When you work on file which deals with many arguments, it is time consuming and not user friendly to always change those arguments inside the python file. Some libraries have been implemented to solve this problem, known as command line parsing library. In python, they are three different solutions: Docopt, Argparse and Click.
In this article I will go in depth in the use of Docopt and not Argparse or Click. I made this choice because after having used all those three methods, I realized that Docopt is by far the most user-friendly way to parse arguments into a file.
The way I will present the Docopt library is by showing you an example of a docopt.py file with the setup.py and requirements.txt file that go with it.
### docopt.py file '''Usage:docopt.py square [options] [operation] [square-option]docopt.py rectangle [options] [operation] [triangle-option]operation:   --area=<bool>       Calculate the area if the argument==True   --perimeter=<bool>  Calculate the perimeter if the argument==Truesquare-option:   --edge=<float>      Edge of the square. [default: 2]rectangle-option:   --height=<float>    Height of the rectangle    --width=<float>     Width of the rectangle '''from docopt import docoptdef area(args):   """   This method computes the area of a square or a rectangle    """      if bool(args['square']):      if args['--edge']:         area = float(args['edge']) ** 2      else:         print("You must specify the edge")   elif bool(args['rectangle']):      if args['--height'] and args['--width']:         area = float(args['--height']) * float(args['--width'])      else:         print("You have forgotten to specify either the height or       the width or both")   return areadef perimeter(args):   """   This method computes the perimeter of a square or a rectangle    """   if bool(args['square']):      if args['--edge']:         perimeter = float(args['edge']) * 2      else:         print("You must specify the edge")   elif bool(args['rectangle']):      if args['--height'] and args['--width']:         perimeter = float(args['--height']) + float(args['--width'])      else:         print("You have forgotten to specify either the height or       the width or both")   return perimeterdef main():   args = docopt(__doc__)   if args['--area']:      area(args)   elif args['--perimeter']:      perimeter(args)   else:      print("command not found")if __name__=='__main__':   main()
They are two parts in the docopt.py file:
the definition of the arguments in the docString
the different methods you want/need to call
In the Usage part you write what will be the calling format of your command line in your terminal. Thus, if I want to call the area operation on a square of edge 5, I will do the following.:
python -m docopt.py square --area=True --edge=5  
As you can see that in the “Usage” part, we can define default values but these values will be overwritten if we specify a value in the command line like we did with the “ — edge” argument.
So let’s decompose the command line:
docopt.py : is the name of the python file that you want to run
square or rectangle are two necessary arguments that we need to give in the command line to run it properly
[options]: is a necessary bracket argument announcing that the following elements will be optional arguments
[operation]: it is composed by two different arguments which are “ — area” and “ — perimeter”. For these two parameters, the value we need to enter in the command line is a boolean. The ‘=<bool>’ is optional but gives a hint of what kind of element the user needs to enter.
[square-option]: it is composed by one argument with a default value
In this part, I will go through the methods ‘area’ and ‘perimeter’ . But before doing so, you notice that you need to import the docopt package and before it you need to install it. However, for the moment forget about the installation, I will give you a clean way to do it after.
You notice that in both methods, when I need an argument from docopt I need to convert it into its proper type. For example args[‘square’] is a boolean but I need to explicitly convert it as a boolean.
Then, the methods for computing the area and the perimeter are pretty basic methods but are optional methods.
Nevertheless, there are two lines at the end of the file which are necessary to run the file properly:
if __name__=='__main__':   main()
Now that we have created our docopt.py file, we can create a setup.py file as long as a requirements.txt file to make our project even more user-friendly.
A setup.py file is a python file where you describe your module distribution to the Distutils, so that the various commands that operate on your modules do the right thing. In this file you can specify which files in your project you want to run and which are the packages required to run the project.
Before diving into the setup.py file you need to have the following architecture in your project:
/docopt-demo   docopt.py   requirements.txt   setup.py
Here is an example of a setup.py file you can write regarding this project:
### setup.py file from setuptools import setupwith open("requirements.txt", "r") as fh:    requirements = fh.readlines()setup(   name = 'docopt-demo',   author = 'JonathanL',   description = 'Example of the setup file for the docopt demo',   version = '0.1.0',   packages = ['docopt-demo'],   install_requires = [req for req in requirements if req[:2] != "# "],   include_package_data=True,   entry_points = {      'console_scripts': [         'docopt = docopt-demo.docopt:main'      ]   })
And here is the requirements.txt file:
# Argument parser packagesdocopt==0.6.2
The first element you have to do it to import setup from setuptools but this package goes with python so if you have python on your computer will have it.
Then, you need to create a list of all the required packages you will parse in the install_requires argument in the setup module.
In the setup module there are some elements you need to be aware of:
packages: should have the same name as the folder you are in so for us it is ‘docopt-demo’
in the ‘console_script’ you can specify a short cut for a specific file. In our case, instead of typing in the terminal :
python -m docopt square --area=True --edge=5
We will just have to enter:
docopt square --area=True --edge=5
In fact, we associate the word ‘docopt’ to the operation ‘docopt-demo.docopt:main’ which is launching the main function in the docopt.py file.
In this file you specify all the packages you need to install to run your project properly.
You have two choices to specify the version:
either you tell the exact version you want to use and you will use the ‘==’ sign
or you can also use operators like ‘>=’ to specify an older version of the package
In this article, I show how to use the Docopt python package which is a very nice way to parse arguments into a file.
I hope you found what you came here for in this article and stay with me for the next episodes of this image recognition trip!
PS: I am currently a Machine Learning Engineer at Unity Technologies recently graduated from a Master of Engineering at UC Berkeley, and if you want to discuss the topic, feel free to reach me. Here is my email.