darusuna.com

Elevate Your Python CLI Development with Typer

Written on

Chapter 1: Introduction to Typer

In the previous week, I introduced one of Python's built-in modules, Argparse, which simplifies the creation of command-line interface (CLI) tools. This module allows users to define both positional and optional arguments effortlessly. Additionally, it generates help documentation automatically, requiring only a brief description for each argument. If you missed that post, you can find it here.

While Argparse is user-friendly, it does come with certain limitations. Thus, in this article, I will introduce Typer, a third-party library that I consider one of the best options for developing Python CLI applications.

Drawbacks of Argparse

The Argparse module has some limitations, which I highlighted in the previous article:

  1. It has a built-in mechanism to determine if an input is an argument or an option, which can lead to unpredictable behavior when commands are incomplete.
  2. It can be challenging to implement more advanced features, such as complex validation of argument values.

These issues are effectively addressed by the widely recognized third-party library, Click. Typer, the main focus of this article, is built on Click's foundation, offering even greater ease of use. With a wealth of tutorials available on Click, I prefer to highlight this less popular but highly promising tool.

It is important to note that Typer builds upon Click, inheriting nearly all its benefits while simplifying usability.

1. Quick Start

To begin, we need to install the Typer library. As is typical, we can use pip:

pip install typer

It's worth noting that Click is Typer's sole dependency, and it will be installed alongside Typer.

Boilerplate Code

Let’s create a simple Python CLI program to send greeting messages, where the user inputs their name. The Python script, greeting.py, is as follows:

import typer

def main(name: str):

typer.echo(f"Hello {name}!")

if __name__ == "__main__":

typer.run(main)

Here’s a brief explanation of the code. First, we import the Typer library. Next, we define a main() function that serves as the entry point for the command-line application, taking a parameter called name. It’s recommended to use type hints to specify the argument type. Finally, we inform Typer to execute the main() function when the script runs.

This approach is simpler than Click and significantly easier than Argparse. Typer automatically infers options and flags from the parameters of the main() function.

Why Use echo()?

You may notice we utilize typer.echo() for output instead of the standard print() function. This feature is inherited from the Click library. The advantage of using echo() is that Click aims to provide consistent support across different environments, ensuring functionality even when configurations are flawed. Thus, using echo() in Typer is advisable for maintaining this robustness. However, we can still resort to using print() if the additional features of echo() aren't necessary.

Demonstration

If we run the script without any arguments, Typer will generate an error message indicating a missing argument:

$ python greeting.py

Of course, it also provides the help documentation:

$ python greeting.py --help

Now, let’s see it in action by passing my name to the program:

$ python greeting.py Chris

These few lines of code can serve as our boilerplate for a Typer-based Python CLI project.

2. Optional Arguments

In the boilerplate example, the name argument is required. To make an argument optional, we can easily assign a default value:

def main(name: str, verbose: bool=False):

typer.echo(f"Hello {name}!")

if verbose:

typer.echo("Program Finished.")

In this case, we’ve added a boolean parameter, verbose, to the main() function and provided it a default value. The help documentation will automatically include this flag, allowing us to control program behavior accordingly.

3. Nesting Commands

One of Click's most notable features is the ability to nest commands, and Typer not only supports this but also simplifies its implementation. Nesting commands allows us to create "sub-commands" within a CLI application. For instance, we might want our greeting.py program to include a farewell feature. With nested commands, we can easily define this separately from the "hello" command, resulting in cleaner code:

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()

In this code, we instantiate a Typer object named main and define two commands, hello and bye, which are both registered accordingly. When we access the help documentation, it will clearly indicate the available commands.

To see the arguments for one of the sub-commands, we can run:

$ python greeting.py bye --help

This nesting command feature enables us to implement complex CLI options requirements with ease.

Summary

In this article, I introduced a third-party Python library for creating CLI programs. Typer significantly simplifies the code required to define CLI applications with options and flags. While it is intuitive and user-friendly, it also possesses the scalability needed to develop more complex applications.

If you find my articles beneficial, please consider supporting me and countless other writers by joining Medium Membership!

The first video titled "The Best way to build a Python command line tool - Python Typer Tutorial" provides an excellent overview of using Typer for CLI development.

The second video, "Click: the Command Line Interface Creation Kit for Python," offers insights into the Click library, which serves as a foundation for Typer.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

# Promising Practices for Reversing Aging and Enhancing Longevity

Explore effective methods to slow the aging process and improve overall health for a longer, fulfilling life.

Living My Best Life: What I No Longer Buy for Happiness

Discover what items I stopped buying to enhance my happiness and embrace a minimalist lifestyle.

Kava Tea: Understanding Its Impact on Mind and Body Wellness

Discover the science behind kava tea's effects on the mind and body, exploring its benefits, risks, and historical significance.

The Dangers of Narcissistic Relationships: Understanding Neurochemistry

Explore how neurochemicals bind individuals to narcissists and the severe impacts on mental health.

Finding My Ikigai: A Transformative Journey to Fulfillment

Discover how I found my ikigai and transformed my life through self-discovery and passion.

Mozilla Alerts Developers: Upcoming User-Agent Changes in Browsers

Mozilla cautions developers about potential issues with upcoming Firefox and Chrome user-agent strings featuring three-digit version numbers.

The Hidden Costs of Death: An Examination of Body Brokers

This article explores the ethical implications of body brokers in the funeral industry, highlighting the challenges faced by families in need.

Finding Freedom from Resentment: Your Path to Healing

Discover how to overcome resentment and embrace self-forgiveness through personal growth and healing.