Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typer #947

Open
1 task
ShellLM opened this issue Nov 13, 2024 · 1 comment
Open
1 task

Typer #947

ShellLM opened this issue Nov 13, 2024 · 1 comment
Labels
CLI-UX Command Line Interface user experience and best practices python Python code, tools, info source-code Code snippets

Comments

@ShellLM
Copy link
Collaborator

ShellLM commented Nov 13, 2024

Typer

Snippet

Typer
Typer


  
 fastapi/typer
0.13.0
15.8k
672
Typer
Features
Learn
Resources
About
Release Notes
Typer
Table of contents
FastAPI of CLIs
Installation
Example
The absolute minimum
Run it
Use Typer in your code
Example upgrade
An example with two subcommands
Run the upgraded example
Recap
Dependencies
typer-slim
License


Typer, build great CLIs. Easy to code. Based on Python type hints.

       

Documentation: https://typer.tiangolo.com

Source Code: https://github.com/fastapi/typer

Content

Typer, build great CLIs. Easy to code. Based on Python type hints.

FastAPI of CLIs

Typer is FastAPI's little sibling, it's the FastAPI of CLIs.

Installation

Create and activate a virtual environment and then install Typer:

pip install typer
████████████████████████████████████████ 100%
Successfully installed typer rich shellingham

Example

The absolute minimum

Create a file main.py with:

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

This script doesn't even use Typer internally. But you can use the typer command to run it as a CLI application.

Run it

Run your application with the typer command:

💬 Run your application
typer main.py run

💬 You get a nice error, you are missing NAME
Usage: typer [PATH_OR_MODULE] run [OPTIONS] NAME
Try 'typer [PATH_OR_MODULE] run --help' for help.
╭─ Error ───────────────────────────────────────────╮
│ Missing argument 'NAME'.                          │
╰───────────────────────────────────────────────────╯


💬 You get a --help for free
typer main.py run --help

Usage: typer [PATH_OR_MODULE] run [OPTIONS] NAME

Run the provided Typer app.

╭─ Arguments ───────────────────────────────────────╮
│ *    name      TEXT  [default: None] [required]   |
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help          Show this message and exit.       │
╰───────────────────────────────────────────────────╯

💬 Now pass the NAME argument
typer main.py run Camila

Hello Camila

💬 It works! 🎉

Use Typer in your code

Now let's start using Typer in your own code, update main.py with:

import typer


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


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

Now you could run it with Python directly:

python main.py Camila
Hello Camila

Example upgrade

This was the simplest example possible.

Now let's see one a bit more complex.

An example with two subcommands

Modify the file main.py.

Create a typer.Typer() app, and create two subcommands with their parameters.

import typer

app = typer.Typer()


@app.command()
def hello(name: str):
    print(f"Hello {name}")


@app.command()
def goodbye(name: str, formal: bool = False):
    if formal:
        print(f"Goodbye Ms. {name}. Have a good day.")
    else:
        print(f"Bye {name}!")


if __name__ == "__main__":
    app()

And that will:

  • Explicitly create a typer.Typer app.
    The previous typer.run actually creates one implicitly for you.
  • Add two subcommands with @app.command().
  • Execute the app() itself, as if it was a function (instead of typer.run).
Run the upgraded example

Check the new help:

❯ python main.py --help
Usage: main.py [OPTIONS] COMMAND [ARGS]...

╭─ Commands ────────────────────────────────────────╮
│ goodbye  Say goodbye                             │
│ hello    Say hello                               │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help          Show this message and exit.       │
╰───────────────────────────────────────────────────╯

Now check the help for the hello command:

❯ python main.py hello --help
Usage: main.py hello [OPTIONS] NAME

Say hello

╭─ Arguments ───────────────────────────────────────╮
│ *    name      TEXT  [required]                   │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help          Show this message and exit.       │
╰───────────────────────────────────────────────────╯

And now check the help for the goodbye command:

❯ python main.py goodbye --help
Usage: main.py goodbye [OPTIONS] NAME

Say goodbye

╭─ Arguments ───────────────────────────────────────╮
│ *    name      TEXT  [required]                   │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --formal / --no-formal                            │
│ --help                             Show this message and exit.       │
╰───────────────────────────────────────────────────╯

Now you can try out the new command line application:

❯ python main.py hello Camila
Hello Camila

❯ python main.py goodbye Camila
Bye Camila!

❯ python main.py goodbye Camila --formal
Goodbye Ms. Camila. Have a good day.

Recap

In summary, you declare once the types of parameters (CLI arguments and CLI options) as function parameters.

You do that with standard modern Python types.

You don't have to learn a new syntax, the methods or classes of a specific library, etc.

Just standard Python.

For example, for an int:

total: int

or for a bool flag:

force: bool

And similarly for files, paths, enums (choices), etc. And there are tools to create groups of subcommands, add metadata, extra validation, etc.

You get: great editor support, including completion and type checks everywhere.

Your users get: automatic --help, auto-completion in their terminal (Bash, Zsh, Fish, PowerShell) when they install your package or when using the typer command.

For a more complete example including more features, see the Tutorial - User Guide.

Dependencies

Typer stands on the shoulders of a giant. Its only internal required dependency is Click.

By default it also comes with extra standard dependencies:

  • rich: to show nicely formatted errors automatically.
  • shellingham: to automatically detect the current shell when installing completion.
    With shellingham you can just use --install-completion.
    Without shellingham, you have to pass the name of the shell to install completion for, e.g. --install-completion bash.

typer-slim

If you don't want the extra standard optional dependencies, install typer-slim instead.

When you install with:

pip install typer

...it includes the same code and dependencies as:

pip install "typer-slim[standard]"

The standard extra dependencies are rich and shellingham.

Note: The typer command is only included in the typer package.

License

This project is licensed under the terms of the MIT license.

Suggested labels

None

@ShellLM ShellLM added CLI-UX Command Line Interface user experience and best practices python Python code, tools, info source-code Code snippets labels Nov 13, 2024
@ShellLM
Copy link
Collaborator Author

ShellLM commented Nov 13, 2024

Related content

#861 similarity score: 0.86
#808 similarity score: 0.86
#929 similarity score: 0.86
#675 similarity score: 0.86
#868 similarity score: 0.86
#683 similarity score: 0.86

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLI-UX Command Line Interface user experience and best practices python Python code, tools, info source-code Code snippets
Projects
None yet
Development

No branches or pull requests

1 participant