Exploring Typer: A User-Friendly Python Command-Line Library
Written on
Typer — A Simplified Approach to Python Command-Line Interfaces
Recently, I discussed the Argparse module, a built-in Python tool for easily creating command-line interfaces (CLIs). This module allows developers to specify both positional and optional arguments while automatically generating help documentation. If you missed that article, you can find it [here](towardsdatascience.com).
While Argparse is user-friendly, it comes with certain limitations. In this article, I will introduce you to Typer, a third-party library that I believe is one of the best options for building Python CLI applications.
Limitations of Argparse
As I mentioned earlier, Argparse has some drawbacks:
- It attempts to automatically determine whether an input is an argument or an option, which can lead to unpredictable behavior with incomplete commands.
- It can be cumbersome when advanced features, such as complex argument value validation, are required.
These concerns are effectively tackled by Click, another third-party library.
For more details, check the [Click Documentation](click.palletsprojects.com).
Typer, the focus of this article, is built on the foundation of Click and makes building CLIs even more straightforward. While there are numerous resources on Click, I want to highlight Typer, which offers greater potential with a simpler interface.
Getting Started with Typer
To begin, we need to install Typer. This can be done easily using pip:
pip install typer
As we can see, Click is a dependency of Typer and will be installed simultaneously.
Basic Example
Let's use a simple example similar to what we did with Argparse. We will create a Python CLI program that sends greeting messages based on user input.
Here’s the code for the script file greeting.py:
import typer
def main(name: str):
typer.echo(f"Hello {name}!")
if __name__ == "__main__":
typer.run(main)
In this code, we import the Typer library and define a main() function, which serves as the entry point for our CLI program. It accepts a parameter called name, and we recommend using type hints for clarity.
Typer intelligently infers options and flags from the parameters of the main() function, making it significantly easier than using Click or Argparse.
Why Use echo()?
You may have noticed that we are using typer.echo() for output instead of the traditional print() function. This design choice is inherited from Click.
The advantage of using echo() is that it maintains consistent functionality across various environments, making it robust even in misconfigured settings. If this feature isn't necessary, you can still opt for print().
Demonstration
When we run this script without any arguments, Typer will generate an error message indicating that an argument is required.
$ python greeting.py
Additionally, Typer will generate helpful documentation for us.
$ python greeting.py --help
Now, let's execute the program by providing my name as input:
$ python greeting.py Chris
This code serves as a solid foundation for a Typer-based Python CLI project.
Optional Arguments
In our initial example, the name argument is mandatory. What if we want to allow an optional argument? This is straightforward; we can simply assign it a default value:
def main(name: str, verbose: bool = False):
typer.echo(f"Hello {name}!")
if verbose:
typer.echo("Program Finished.")
Now, if we call the help documentation, the optional flag will be automatically generated.
Nesting Commands
Typer also supports nesting commands, which is one of Click’s notable features. This allows us to define sub-commands within a CLI application. For example, we can enhance our greeting.py program to include a goodbye feature.
Here’s how to implement it:
import typer
main = typer.Typer()
@main.command() def hello(name: str, verbose: bool = False):
typer.echo(f"Hello {name}!")
if verbose:
typer.echo("Program Finished.")
@main.command() def bye(name: str, verbose: bool = False):
typer.echo(f"Goodbye {name}!")
if verbose:
typer.echo("Thank you for using this program.")
if __name__ == "__main__":
main()
With this structure, we create a Typer object and define two commands. The help documentation will now reflect both commands.
Summary
In this article, I introduced Typer, a third-party Python library designed for creating CLI applications with minimal code. It simplifies the process of defining command-line options and flags while also being scalable enough for more complex applications.