top of page

Typer - The Command Line Script Framework for Python

Typer is a command line interface (CLI) framework for python that utilizes the pydantic type framework. This framework has turned out to be one of the easiest to use and cleanest to implement for sub parser oriented projects (especially compared to argparse ).

Typer is a library for building CLI applications that users will love using and developers will love creating. Based on Python 3.6+ type hints.

The key features are:

  • Intuitive to write: Great editor support. Completion everywhere. Less time debugging. Designed to be easy to use and learn. Less time reading docs.

  • Easy to use: It's easy to use for the final users. Automatic help, and automatic completion for all shells.

  • Short: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.

  • Start simple: The simplest example adds only 2 lines of code to your app: 1 import, 1 function call.

  • Grow large: Grow in complexity as much as you want, create arbitrarily complex trees of commands and groups of subcommands, with options and arguments.

To install Typer, type:

pip install typer

CLI Arguments

Arguments are required positional inputs users will need to provide. There are two primary ways to specify arguments.

Arguments can also be made optional using this type annotation, however the typer. Option object operates this way by default as seen next.

CLI Options

Options are actually quite similar in functionality to Optional Arguments but they have a few extra features that Arguments do not.

One way typer.Option is different from typer.Argument is that it can be configured to prompt the user for input.

A really useful feature that is easy to miss is the password and confirmation_prompt settings. These are great for giving users a normalized experience when dealing with sensitive data.

Argument Choices

The ability to force users to choose one of a few specific choices is very handy in more situations than you’d think. Typer makes this easy using enum.Enum types.

CLI Subparsers

In large projects its quite possible you might want to separate different CLI’s into separate scripts that are leveraged by one primary CLI instead of putting everything in one long CLI script. Typer makes this really easy using the typer.Typer().add_typer(...) method.

in this example items and users are separate CLI python modules with their own Typer apps —

Other Useful Features

  • Colors and integration with Colorama —

  • Progress Bar support — typer.progressbar()

  • launch websites automatically — typer.launch("")

  • prompt users for input — typer.prompt("What is your name?")

  • gracefully terminate a program — raise typer.Exit()

  • being built on Click, Typer can use packages like

Starter Code

This is a template I have developed over time that I start new projects with. It has nice starting Typer configuration and has examples for subparsers, documentation and CLI command with and without arguments.

Copyright <<year>> <<insert publisher name>>

    this is a sample Typer CLI layout
    > python example_cmd

# ::IMPORTS ------------------------------------------------------------ #
# cli framework -
import typer

# data types for validation -
from typing import Optional

# cross platform path handling -
from pathlib import Path

# ::SETUP -------------------------------------------------------------- #
app = typer.Typer(add_completion=False)

# ::SETUP SUBPARSERS --------------------------------------------------- #
# app.add_typer(<<>>, name="subparser")

# ::CORE LOGIC --------------------------------------------------------- #
# place core script logic here and call functions
# from the cli command functions to separate CLI from business logic

# ::CLI ---------------------------------------------------------------- #
def example_cmd():
    print("hello typer!")
def example_cmd_args(
    name: str,
    last_name: str =  typer.Option(default="<unknown>"),
    age: Optional[str] =typer.Argument(None),
    print(f"name:{name}  last-name:{last_name}  age:{age}")
# ::EXECUTE ------------------------------------------------------------ #
def main():
if __name__=="__main__":  # ensure importing the script will not execute

Resource: Medium - Robby Boney

The Tech Platform

bottom of page