Building CLIs With python-fire
This is Day 6 of the #100DaysOfPython challenge.
This post will use the Python Fire library to work through a simple example of setting up the library.
Let's create the
hello-fire directory and install
We will also create a file
cli.py to hold our CLI script.
# Make the `hello-fire` directory $ mkdir hello-fire $ cd hello-fire # Make file the CLI script $ touch cli.py # Init the virtual environment $ pipenv --three $ pipenv install python-fire
We are now ready to add a script.
The CLI script
For our demo example, we are going to take a slightly modified version of grouping commands script to demo how to run subcommands.
Our aim is to have the following commands:
|Print a message to the console to highlight that we have run the ingestion script|
|Print a message based on the value of the Digestion class |
|Print a message to the console to highlight that we have run the digestion script and set the value of satiated to |
|Run both ingestion and digestion |
Adding the code
We set the base commands through the
Pipeline class and the subcommands through their own class that is initiated as properties of the
If you notice the optional
volume argument for
DigestionStage.run, it is used to set the volume of the
Digestion class based on an argument passed to the CLI (defaulting to 1).
#!/usr/bin/env python import fire class IngestionStage(object): def run(self): return 'Ingesting! Nom nom nom...' class DigestionStage(object): def __init__(self): self.satiated = False def run(self, volume: int = 1) -> str: self.satiated = True return ' '.join(['Burp!'] * volume) def status(self): return 'Satiated.' if self.satiated else 'Not satiated.' class Pipeline(object): def __init__(self): self.ingestion = IngestionStage() self.digestion = DigestionStage() def run(self): print(self.ingestion.run()) print(self.digestion.run()) print(self.digestion.status()) return 'Pipeline complete' if __name__ == '__main__': fire.Fire(Pipeline)
Running the script
To run the script, we need to ensure we are running the Pipenv virtual environment.
We can do this with
Once, in the shell, we can run our script and see the results:
$ python cli.py ingestion run # Ingesting! Nom nom nom... $ python cli.py digestion run # Burp! $ python cli.py digestion run --volume=10 # Burp! Burp! Burp! Burp! Burp! Burp! Burp! Burp! Burp! Burp! $ python cli.py status # Not satiated. $ python cli.py run # Ingesting! Nom nom nom... # Burp! # Satiated. # Pipeline complete
Running through our script, we can now see the results of our work.
Notice that the
status property of the Digestion class is set to
True when we run the
run command and the number of "Burp!" messages printed is based on the
volume argument passed to the
Today's post demonstrated how to use the
python-fire package to write easier CLI scripts with their own subcommands and instance-managed state.
Of most languages that I have used, it must be said that
python-fire has been one of the most approachable libraries I have seen for building out CLI tools.
Resources and further reading
Photo credit: cullansmith
1,200+ PEOPLE ALREADY JOINED ❤️️
Get fresh posts + news direct to your inbox.
No spam. We only send you relevant content.