Automated python arguments with Google Fire

Spend less time documenting and more time programming. We look at a couple simple apps that use the Python Fire library to create automated command line interfaces.

Tim the Enchanter from Monty Python

It’s the hottest thing to drop from Google for the open source community since TensorFlow [1].

Err well, it’s not quite as popular…

What’s interesting to me about the deep learning library TensorFlow is there were already a few popular deep learning libraries on the market (namely, Theano, Caffe and Torch) when it was released. Even still, TensorFlow immediately and persistently garnered interest, check out the stackoverflow activity:

source: http://deliprao.com/archives/168

Fire is similar in the sense that a bunch of perfectly good tools for automating command line interfaces (CLIs) already exist for python programmers [2]. It will be interesting to see if Fire is adopted by a significant portion of the user base.

Update: After using Fire for a few weeks and comparing with other options such as Click, I’ve realized that Fire is more suited for rapid development as it lacks many features of other CLIs. However, new features are being developed. The initial release carried IPython around as a dependency, which lead to long load times for even simple scripts, but this is now an optional dependency!

A simple app with Fire

Fire can be installed using pip:

pip install fire

The documentation is on github. It contained an insightful note:

We can do this by calling fire.Fire(my_object) where my_object can be a function, class or other object.

Now time to make the app. It will be a random sample generator. The random_sample function will be computed viaFire. As we’ll see, the values returned by the function are printed.

Just show me the code.

Our random_sample function is fed into the Fire method, which automatically creates command line arguments for the function parameters. Instead of writing usage instructions for the script, the user can be instructed to run python main.py -- --help which results in this output:

Generating usage instructions with Google Fire

Here is an example of the script’s usage:

>>> python main.py 'Bohr, Schrodinger, Einstein, Dirac' --num-samples 4 --seed 1905
Choices: ('Bohr', 'Schrodinger', 'Einstein', 'Dirac')
Genreating 4 samples
Random seed: 1905
Samples:
Dirac
Einstein
Dirac
Schrodinger
By the way, if you want to run the script as an executable (i.e. ./main.py instead of python main.py) then add a line like this to the top:
#!/usr/bin/env python
and give the script permission to run with the command chmod +x main.py

Interactive Mode

My favorite feature of Fire is that it can throw you into an IPython REPL environment. All you have to do it add -- --interactive to the end of your script call. For example:

>>> python main.py 'Bohr, Schrodinger, Einstein, Dirac' --num-samples 4 
--seed 1905 -- --interactive
1. Running main.py
2. Print output from main.py
3. Notice the modules and object that have been loaded?
4. Launching the IPython interpreter
5. Printing the results

The data returned from the function call has now been stored in memory, along with the function itself. Below we get the docstring and then run a new sampling computation.

The choice arguments are passed as a tuple, whereas they would be input as a string using the command line interface:

>>> python main.py 'Bohr, Schrodinger' --num-samples 2 --seed 3

Firing a class

You can feed in any object to the Fire module and have the library build a CLI. Here is a an example where we use a class.

Our WikiPage class requests a wikipedia page and the get_html_element module will try and find an html element on the page (note: always use a parsing library like BeautifulSoup to find html elements — not regex like me!).

Let’s look at the usage:

Passing a page argument results in another helpful usage message:

For example we can get the status code:

>>> python main.py --page https://en.wikipedia.org/wiki/History_of_quantum_mechanics status-code
200

Or generate a random page and check the URL:

>>> python main.py url
https://en.wikipedia.org/wiki/Parasicydium_bandama

We can also call modules directly from the command line:

For example:

>>> python main.py --page https://en.wikipedia.org/wiki/History_of_quantum_mechanics get-html-element title
History of quantum mechanics - Wikipedia

Happy automating!

Thanks for reading. You can find me on twitter @agalea91

[1] Google Fire release announcement

[2] Other CLI libraries for python