Skip to content

First Stepsยถ

The simplest exampleยถ

The simplest Typer file could look like this:

import typer


def main():
    print("Hello World")


if __name__ == "__main__":
    typer.run(main)

Copy that to a file main.py.

Test it:

fast โ†’python main.py
Hello World


python main.py --help
Usage: main.py [OPTIONS]

โ•ญโ”€ Options โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ --help Show this message โ”‚
โ”‚ and exit. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

restart โ†ป

...but this program is still not very useful. Let's extend it.

What is a CLI argumentยถ

Here we will use the word CLI argument to refer to CLI parameters passed in some specific order to the CLI application. By default, they are required.

If you go to your terminal and type:

fast โ†’ls ./myproject
first-steps.md intro.md

restart โ†ป

ls will show the contents of the directory ./myproject.

  • ls is the program (or "command", "CLI app").
  • ./myproject is a CLI argument, in this case it refers to the path of a directory.

They are a bit different from CLI options that you will see later below.

Add a CLI argumentยถ

Update the previous example with an argument name:

import typer


def main(name: str):
    print(f"Hello {name}")


if __name__ == "__main__":
    typer.run(main)
fast โ†’python main.py
Usage: main.py [OPTIONS] NAME
Try 'main.py --help' for help.
โ•ญโ”€ Error โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Missing argument 'NAME'. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

python main.py Camila
Hello Camila


python main.py "Camila Gutiรฉrrez"
Hello Camila Gutiรฉrrez

restart โ†ป

Tip

If you need to pass a single value that contains spaces to a CLI argument, use quotes (") around it.

Two CLI argumentsยถ

Now let's say we want to have the name and last name separated.

So, extend that to have 2 arguments, name and lastname:

import typer


def main(name: str, lastname: str):
    print(f"Hello {name} {lastname}")


if __name__ == "__main__":
    typer.run(main)
fast โ†’python main.py --help
Usage: main.py [OPTIONS] NAME
Try 'main.py --help' for help.
โ•ญโ”€ Error โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Missing argument 'NAME'. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

typer on ๎‚  richify [ยป!?] via ๐Ÿ v3.7.5 (env3.7)
โฏ python main.py
Usage: main.py [OPTIONS] NAME LASTNAME
Try 'main.py --help' for help.
โ•ญโ”€ Error โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Missing argument 'NAME'. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ


python main.py Camila
Usage: main.py [OPTIONS] NAME LASTNAME
Try 'main.py --help' for help.
โ•ญโ”€ Error โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Missing argument 'LASTNAME'. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

python main.py Camila Gutiรฉrrez
Hello Camila Gutiรฉrrez

restart โ†ป

Tip

Notice that the order is important. The last name has to go after the first name.

If you called it with:

$ python main.py Gutiรฉrrez Camila

your app wouldn't have a way to know which is the name and which the lastname. It expects the first CLI argument to be the name and the second CLI argument to be the lastname.

What is a CLI optionยถ

Here we will use the word CLI option to refer to CLI parameters passed to the CLI application with a specific name. For example, if you go to your terminal and type:

fast โ†’ls ./myproject --size
12 first-steps.md 4 intro.md

restart โ†ป

ls will show the contents of the directory ./myproject with their size.

  • ls is the program (or "command", "CLI app").
  • ./myproject is a CLI argument.
  • --size is an optional CLI option.

The program knows it has to show the size because it sees --size, not because of the order.

A CLI option like --size doesn't depend on the order like a CLI argument.

So, if you put the --size before the CLI argument, it still works (in fact, that's the most common way of doing it):

fast โ†’ls --size ./myproject
12 first-steps.md 4 intro.md

restart โ†ป

The main visual difference between a CLI option and a CLI argument is that the CLI option has -- prepended to the name, like in "--size".

A CLI option doesn't depend on the order because it has a predefined name (here it's --size). This is because the CLI app is looking specifically for a literal --size parameter (also known as "flag" or "switch"), with that specific "name" (here the specific name is "--size"). The CLI app will check if you typed it or not, it will be actively looking for --size even if you didn't type it (to check if it's there or not).

In contrast, the CLI app is not actively looking for the CLI argument with a text "./myproject", it has no way to know if you would type ./myproject or ./my-super-awesome-project or anything else. It's just waiting to get whatever you give it. The only way to know that you refer to a specific CLI argument is because of the order. The same way that it knows that the first CLI argument was the name and the second was the lastname, but if you mixed the order, it wouldn't be able to handle it.

Instead, with a CLI option, the order doesn't matter.

Also, by default, a CLI option is optional (not required).

So, by default:

  • A CLI argument is required
  • A CLI option is optional

But the required and optional defaults can be changed.

So, the main and most important difference is that:

  • CLI options start with -- and don't depend on the order
  • CLI arguments depend on the sequence order

Tip

In this example above the CLI option --size is just a "flag" or "switch" that will contain a boolean value, True or False, depending on if it was added to the command or not.

This one doesn't receive any values. But CLI options can also receive values like CLI arguments. You'll see how later.

Add one CLI optionยถ

Now add a --formal CLI option:

import typer


def main(name: str, lastname: str, formal: bool = False):
    if formal:
        print(f"Good day Ms. {name} {lastname}.")
    else:
        print(f"Hello {name} {lastname}")


if __name__ == "__main__":
    typer.run(main)

Here formal is a bool that is False by default.

fast โ†’python main.py --help
Usage: main.py [OPTIONS] NAME LASTNAME

โ•ญโ”€ Arguments โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ * name TEXT [default: None] [required] โ”‚
โ”‚ * lastname TEXT [default: None] [required] โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€ Options โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ --formal --no-formal [default: no-formal] โ”‚
โ”‚ --help Show this message and โ”‚
โ”‚ exit. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

restart โ†ป

Tip

Notice that it automatically creates a --formal and a --no-formal because it detected that formal is a bool.

Now call it normally:

fast โ†’python main.py Camila Gutiรฉrrez
Hello Camila Gutiรฉrrez

python main.py Camila Gutiรฉrrez --formal
Good day Ms. Camila Gutiรฉrrez.

python main.py Camila --formal Gutiรฉrrez
Good day Ms. Camila Gutiรฉrrez.

python main.py --formal Camila Gutiรฉrrez
Good day Ms. Camila Gutiรฉrrez.

restart โ†ป

A CLI option with a valueยถ

To convert the lastname from a CLI argument to a CLI option, give it a default value of "":

import typer


def main(name: str, lastname: str = "", formal: bool = False):
    if formal:
        print(f"Good day Ms. {name} {lastname}.")
    else:
        print(f"Hello {name} {lastname}")


if __name__ == "__main__":
    typer.run(main)

As lastname now has a default value of "" (an empty string) it is no longer required in the function, and Typer will now by default make it an optional CLI option.

fast โ†’python main.py --help
Usage: main.py [OPTIONS] NAME

โ•ญโ”€ Arguments โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ * name TEXT [default: None] [required] โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€ Options โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ --lastname TEXT โ”‚
โ”‚ --formal --no-formal [default: no-formal] โ”‚
โ”‚ --help Show this message โ”‚
โ”‚ and exit. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

restart โ†ป

Tip

Notice the --lastname, and notice that it takes a textual value.

A CLI option with a value like --lastname (contrary to a CLI option without a value, a bool flag, like --formal or --size) takes as its value whatever is at the right side of the CLI option.

fast โ†’python main.py Camila
Hello Camila

python main.py Camila --lastname Gutiรฉrrez
Hello Camila Gutiรฉrrez

restart โ†ป

Tip

Notice that "Gutiรฉrrez" is at the right side of --lastname. A CLI option with a value takes as its value whatever is at the right side.

And as --lastname is now a CLI option that doesn't depend on the order, you can pass it before the name:

fast โ†’python main.py --lastname Gutiรฉrrez Camila
Hello Camila Gutiรฉrrez

restart โ†ป

Document your CLI appยถ

If you add a docstring to your function it will be used in the help text:

import typer


def main(name: str, lastname: str = "", formal: bool = False):
    """
    Say hi to NAME, optionally with a --lastname.

    If --formal is used, say hi very formally.
    """
    if formal:
        print(f"Good day Ms. {name} {lastname}.")
    else:
        print(f"Hello {name} {lastname}")


if __name__ == "__main__":
    typer.run(main)

Now see it with the --help option:

fast โ†’python main.py --help
Usage: main.py [OPTIONS] NAME

Say hi to NAME, optionally with a --lastname.
If --formal is used, say hi very formally.

โ•ญโ”€ Arguments โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ * name TEXT [default: None] [required] โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€ Options โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ --lastname TEXT โ”‚
โ”‚ --formal --no-formal [default: no-formal] โ”‚
โ”‚ --help Show this message โ”‚
โ”‚ and exit. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

restart โ†ป

Tip

There is another place to document the specific CLI options and CLI arguments that will show up next to them in the help text as with --install-completion or --help, you will learn that later in the tutorial.

Arguments, options, parameters, optional, requiredยถ

Be aware that these terms refer to multiple things depending on the context, and sadly, those "contexts" mix frequently, so it's easy to get confused.

In Pythonยถ

In Python, the names of the variables in a function, like name and lastname:

def main(name: str, lastname: str = ""):
    pass

are called "Python function parameters" or "Python function arguments".

Technical Details

There's actually a very small distinction in Python between "parameter" and "argument".

It's quite technical... and somewhat pedantic.

Parameter refers to the variable name in a function declaration. Like:

def bring_person(name: str, lastname: str = ""):
    pass

Argument refers to the value passed when calling a function. Like:

person = bring_person("Camila", lastname="Gutiรฉrrez")

...but you will probably see them used interchangeably in most of the places (including here).

Python default valuesยถ

In Python, in a function, a parameter with a default value like lastname in:

def main(name: str, lastname: str = ""):
    pass

is considered an "optional parameter" (or "optional argument").

The default value can be anything, like "" or None.

And a parameter like name, that doesn't have a default value, is considered required.

In CLIsยถ

When talking about command line interface applications, the words "argument" and "parameter" are commonly used to refer to that data passed to a CLI app, those parameters.

But those words don't imply anything about the data being required, needing to be passed in a certain order, nor having a flag like --lastname.

The parameters that come with a name like --lastname (and optionally a value) are commonly optional, not required. So, when talking about CLIs it's common to call them optional arguments or optional parameters. Sometimes these optional parameters that start with -- are also called a flag or a switch.

In reality, the parameters that require an order can be made optional too. And the ones that come with a flag (like --lastname) can be required too.

In Typerยถ

To try and make it a bit easier, we'll normally use the words "parameter" or "argument" to refer to Python functions.

We'll use CLI argument to refer to those CLI parameters that depend on the specific order. That are required by default.

And we'll use CLI option to refer to those CLI parameters that depend on a name that starts with -- (like --lastname). That are optional by default.

We will use CLI parameter to refer to both, CLI arguments and CLI options.

The typer Commandยถ

When you install typer, by default it adds a typer command to your shell.

This typer command allows you to run your scripts with โœจ auto completion โœจ in your terminal.

As an alternative to running with Python:

fast โ†’python main.py
Hello World

restart โ†ป

You can run with the typer command:

fast โ†’typer main.py run
Hello World

restart โ†ป

...and it will give you auto completion in your terminal when you hit TAB for all your code.

So you can use it to have auto completion for your own scripts as you continue with the tutorial.

Tip

Your CLI application built with Typer won't need the typer command to have auto completion once you create a Python package.

But for short scripts and for learning, before creating a Python package, it might be useful.

Was this page helpful?