Popular searches
//

Let's build a modern CMD tool with Python using Typer and Rich

14.10.2022 | 10 minutes reading time

Let's build a modern CMD tool with Python using Typer and Rich

I often have a need for a small CMD tool for my projects - e.g. to query an API or perform some operation. What do I want from the tool?

  • Quick development cycle
  • Nice output, e.g. with syntax Highlighting for JSON or Tables.
  • Easy to install for all people in the project
  • Some documentation so I know what it does a few days later.

Most projects I've seen use Bash for that, but that has a couple of drawbacks:

  • Its not portable, e.g. if you have windows users in your team they will have a harder time to run that
  • It does not really grow if your tool becomes more complex
  • Not that many people can write good bash scripts
  • It's output is usually ugly

Good alternatives are, at least for me, Powershell and Python. While Powershell is powerful and portable, its less well known than Python so I will focus on Python here.

As an example, I will walk through how to create such a tool by using the Star Wars API and show how to build a nice client for that.

How to install the Python environment?

While there are lots of tools to install Python nowadays, I use Poetry for my projects. It's easy to use and usually just does it's job.

Please install it and see the documentation above. You will also need a modernish Python Version to follow along. I use Python 3.10 but everything from 3.5 should work.

Setup

First create a new Project using Poetry

Just answer the questions poetry asks you (pressing enter is enough for this tutorial) and choose no if it asks for interactice dependencies.

For me it looks like this:

Now we need just two dependencies: typer and httpx. Typer is a package designed to build CMD tools fast by leveraging several modern Python features like type hinting. It also installs the rich package which is very good at displaying gorgeous output. HTTPX is a REST client for python.

Please create now a file called api.py and open it in your favorite editor.

We need some boilerplate, but it's not much:

This does not actually do anything but it's the minimum to get started.

First task: Lets query the API for a list of all vehicles

I want to get a list of all known Star Wars vehicles and their passenger capacity.

For that we have to query this URL: https://swapi.dev/api/vehicles/

Lets add a command for that:

Now we can start using our client:

If you look at the help you will notice that typer automatically created the help content for us, using the descriptions of the commands. It also transforms the function names into commands, e.g. get_vehicles is turned into get-vehicles.

Lets get the list of vehicles:

While this works its not readable at all and would need serious post processing. Luckily rich can auto-format JSON using its very versatile print method:

The output is now much more readable:

Thats much better! But we can do even more using rich: We can easily output a table just showing the relevant information.

I've added a table using rich, and the output now looks like:

Thats much easier to parse and understand. Rich also supports much more advanced output, e.g. progress bars, diagrams and much more. While I seldom use all of it in a project, its advanced capabilities are really helpful to make the output easier to understand. As an example: For a project of mine I query an API every 5 Seconds and watch for changes in the state. If there is a change, I simply output the field in red. While that does not sound like much, it's super helpful if you have ~50 fields and need to look for changes.

Second task: Add some commands

While showing of rich is super easy, you should not dismiss typish at all - while its ability to create help output is valuable it really shines if you need to accept input from the command line. It can validate the input against the type given in the function signature, eliminating the need for lots of boiler plate code. Lets add a quick example: We want to add the option to filter by the film (Valid options 1,2,3) and the number of passengers (any positive integer is valid)

Ok how we can use this? Typer autogenerates a help for us

Lets try it:

All passengers but only film 5:

More than 10 passengers and all films:

More than 10 passengers and film 3:

Conclusion

This quick tutorial only scratched the surface of what's possible with Typer and Rich. Both tools together really simplify the creation of useful CMD tools. Since I discovered them, I build more helper tools for my projects than before - simply because they are easier to built and maintain than ever before.

//

More articles in this subject area

Discover exciting further topics and let the codecentric world inspire you.