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

Overview

Typer

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

Test Publish Coverage Package version


Documentation: https://typer.tiangolo.com

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


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.

FastAPI of CLIs

Typer is FastAPI's little sibling.

And it's intended to be the FastAPI of CLIs.

Requirements

Python 3.6+

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

Installation

$ pip install typer
---> 100%
Successfully installed typer

Example

The absolute minimum

  • Create a file main.py with:
import typer


def main(name: str):
    typer.echo(f"Hello {name}")


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

Run it

Run your application:

// Run your application
$ python main.py

// You get a nice error, you are missing NAME
Usage: main.py [OPTIONS] NAME
Try "main.py --help" for help.

Error: Missing argument 'NAME'.

// You get a --help for free
$ python main.py --help

Usage: main.py [OPTIONS] NAME

Arguments:
  NAME  [required]

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

// When you create a package you get ✨ auto-completion ✨ for free, installed with --install-completion

// Now pass the NAME argument
$ python main.py Camila

Hello Camila

// It works! 🎉

Note: auto-completion works when you create a Python package and run it with --install-completion or when you use Typer CLI.

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):
    typer.echo(f"Hello {name}")


@app.command()
def goodbye(name: str, formal: bool = False):
    if formal:
        typer.echo(f"Goodbye Ms. {name}. Have a good day.")
    else:
        typer.echo(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 --help
$ python main.py --help

Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  goodbye
  hello

// You have 2 subcommands (the 2 functions): goodbye and hello

// Now get the --help for hello

$ python main.py hello --help

Usage: main.py hello [OPTIONS] NAME

Arguments:
  NAME  [required]

Options:
  --help  Show this message and exit.

// And now get the --help for goodbye

$ python main.py goodbye --help

Usage: main.py goodbye [OPTIONS] NAME

Arguments:
  NAME  [required]

Options:
  --formal / --no-formal  [default: False]
  --help                  Show this message and exit.

// Automatic --formal and --no-formal for the bool option 🎉

// And if you use it with the hello command

$ python main.py hello Camila

Hello Camila

// And with the goodbye command

$ python main.py goodbye Camila

Bye Camila!

// And with --formal

$ python main.py goodbye --formal Camila

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 3.6+.

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 Typer CLI.

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

Optional Dependencies

Typer uses Click internally. That's the only dependency.

But you can also install extras:

  • colorama: and Click will automatically use it to make sure your terminal's colors always work correctly, even in Windows.
    • Then you can use any tool you want to output your terminal's colors in all the systems, including the integrated typer.style() and typer.secho() (provided by Click).
    • Or any other tool, e.g. wasabi, blessings.
  • shellingham: and Typer will 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.

You can install typer with colorama and shellingham with pip install typer[all].

Other tools and plug-ins

Click has many plug-ins available that you can use. And there are many tools that help with command line applications that you can use as well, even if they are not related to Typer or Click.

For example:

  • click-spinner: to show the user that you are loading data. A Click plug-in.
    • There are several other Click plug-ins at click-contrib that you can explore.
  • tabulate: to automatically display tabular data nicely. Independent of Click or Typer.
  • tqdm: a fast, extensible progress bar, alternative to Typer's own typer.progressbar().
  • etc... you can re-use many of the great available tools for building CLIs.

License

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

Comments
  • ImportError: cannot import name 'get_terminal_size' from 'click.termui'

    ImportError: cannot import name 'get_terminal_size' from 'click.termui'

    First Check

    • [X] I added a very descriptive title to this issue.
    • [X] I used the GitHub search to find a similar issue and didn't find it.
    • [X] I searched the Typer documentation, with the integrated search.
    • [X] I already searched in Google "How to X in Typer" and didn't find any information.
    • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
    • [X] I already checked if it is not related to Typer but to Click.

    Commit to Help

    • [X] I commit to help with one of those options 👆

    Example Code

    import typer
    

    Description

    • Install latest versions of typer (0.4.0) and click (8.1.0)
    • Run script with single line import typer
    • Import fails due to method get_terminal_size having been removed in click 8.1.0 (https://github.com/pallets/click/pull/2130)
    Traceback (most recent call last):
      File "test.py", line 1, in <module>
        import typer
      File "/.venv/lib/python3.8/site-packages/typer/__init__.py", line 12, in <module>
        from click.termui import get_terminal_size as get_terminal_size
    ImportError: cannot import name 'get_terminal_size' from 'click.termui' (/.venv/lib/python3.8/site-packages/click/termui.py)
    

    Operating System

    Linux

    Operating System Details

    Ubunutu 20.04

    Typer Version

    0.4.0

    Python Version

    Python 3.8.10

    Additional Context

    No response

    question answered 
    opened by jmhummel 27
  • running typer cli command from python code

    running typer cli command from python code

    How can i trigger/run typer cli specific command from python code. I guess i need to emulate command line arguments some where but not sure. Can you please help on this?

    Cli: python main.py goodbye --formal Camila

    From Code: i want to run specific command based on my need. how do i pass command line arguments, some thing like: typer_app( "goodbye --formal Camila" )

    question answered 
    opened by blnprasad 22
  • [FEATURE] Handling Mutliple Variable Length Arguments

    [FEATURE] Handling Mutliple Variable Length Arguments

    I'm not familiar with the internals of typer and whether this is feasible, but it would be nice if it were possible to implement a command like the following:

    from typing import Optional, List
    
    import typer
    
    app = typer.Typer()
    
    
    @app.command()
    def main(first_list: List[str], option: bool = False, second_list: List[str] = ()):
        print(first_list, second_list)
    

    Where the expected behavior is:

    $ python main.py a b c --option d e f
    ('a', 'b', 'c') ('d', 'e', 'f')
    $ python main.py a b c d e f --option
    ('a', 'b', 'c', 'd', 'e', 'f') ()
    $ python main.py a b c d e f
    ('a', 'b', 'c', 'd', 'e', 'f') ()
    

    However the actual behavior in this case does not adhere to the above:

    $ python main.py a b c --option d e f
    ('a', 'b', 'c', 'd', 'e', 'f') True ()
    

    This can presently be achieved in argparse quite concisely:

    import argparse
    
    def main():
        cli = argparse.ArgumentParser()
        cli.add_argument(
            "first_list", nargs="*", type=str,
        )
        cli.add_argument(
            "--option", nargs="*", type=str, default=[],
        )
        args = cli.parse_args()
        print(args.first_list, args.option)
    
    enhancement answered 
    opened by rmorshea 17
  • [QUESTION] Dependency Injection

    [QUESTION] Dependency Injection

    First check

    • [X] I used the GitHub search to find a similar issue and didn't find it.
    • [X] I searched the Typer documentation, with the integrated search.
    • [X] I already searched in Google "How to X in Typer" and didn't find any information.
    • [X] I already searched in Google "How to X in Click" and didn't find any information.

    First of all, thank you for your amazing tools, it helps my team and I to build great products !

    Description

    How can I inject a Database connection to a "cli function" ?

    I was looking for a mecanism like Depends in FastAPI (https://fastapi.tiangolo.com/tutorial/dependencies/)

    Additional context

    I'm trying to create a cli which read files and insert them to a database but one of my subcommands is depending of a Database connection.

    For the moment I've used:

    save_app = typer.Typer()
    
    
    def get_db():
        typer.echo("Initializing database")
        db = VerticaDB(
            host=conf.get_vertica_host(),
            port=conf.get_vertica_port(),
            user=conf.get_vertica_user(),
            password=conf.get_vertica_password(),
            database=conf.get_vertica_database()
        )
        return db
    
    
    @save_app.command("save")
    def ingest_snitch_file(
            path_to_log_file: Path = typer.Option(
                ...,
                exists=True,
                readable=True,
                envvar='PATH_TO_SNITCH_FILE'
            ),
            db=typer.Option(
                hidden=True,
                default=get_db()
            )
    ):
        """
        Ingest snitch files to Database
        """
        snitch = Snitch(
            db=db,
            path_to_snitch=path_to_log_file,
            table_schema=conf.get_vertica_table_schema(),
            table_name=conf.get_vertica_table_name()
        )
        snitch.insert_log_to_database()
    
    question 
    opened by Leletir 17
  • ✨ Richify, add integrations with Rich everywhere

    ✨ Richify, add integrations with Rich everywhere

    ✨ Richify, add integrations with Rich everywhere.

    This started with a copy of https://github.com/ewels/rich-click, and started evolving from there with several refactors.

    Rich is still an optional dependency, but when installed, it's used in several places.


    This PR includes several things related to the new deep integration with Rich.

    Use standard print

    Now typer.echo() is no longer recommended, for the simplest cases, standard print() is recommended and documented.

    And for more complex cases, Rich is recommended. Several places in the docs have been updated to recommend Rich, e.g. the whole section for "Printing and Colors".

    Rich for --help

    When Rich is installed, it's used to format all the output of --help commands.

    New docs for deprecated

    New docs for the deprecated parameter in commands, it includes special formatting and handling with Rich.

    Rich Markup and Markdown

    Rich Markup and Markdown can be enabled with a new parameter rich_markup_mode that can be None, "rich", "markdown".

    Including a new section in the docs for it.

    When using "rich" the content in help strings, epilog and docstrings is parsed with Rich Markup, when "markdown" is used, then it's parsed with Rich Markdown.

    Help Panels

    There's a new parameter rich_help_panel in typer.Typer(),app.add_typer(), app.command(), typer.Argument(), and typer.Option().

    Setting it to a name will render that component in a Rich panel in the help from the --help option.

    New docs for that in the sections about help for CLI arguments, CLI options, and commands.

    Epilog docs

    New docs for using the epilog, also rendered with Rich.

    Tests

    Updated tests and many new tests to keep 100% of test coverage with the new Rich utils and integrations.

    opened by tiangolo 13
  • Default to add_completion == False in typer.run

    Default to add_completion == False in typer.run

    First Check

    • [X] I added a very descriptive title to this issue.
    • [X] I used the GitHub search to find a similar issue and didn't find it.
    • [X] I searched the Typer documentation, with the integrated search.
    • [X] I already searched in Google "How to X in Typer" and didn't find any information.
    • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
    • [X] I already checked if it is not related to Typer but to Click.

    Commit to Help

    • [X] I commit to help with one of those options 👆

    Example Code

    from typing import Any, Callable
    import typer
    
    # Have typer.run() behave like:
    
    
    def run(function: Callable[..., Any], add_completion: bool = False) -> Any:
        app = typer.Typer(add_completion=add_completion)
        app.command()(function)
        app()
    
    
    def main(name: str) -> None:
        print(f"Hello, {name}!")
    
    
    if __name__ == "__main__":
        run(main)  # defaults to suppressing completion installation options:
    #   --install-completion [bash|zsh|fish|powershell|pwsh]
    #                                   Install completion for the specified shell.
    #   --show-completion [bash|zsh|fish|powershell|pwsh]
    #                                   Show completion for the specified shell, to
    #                                   copy it or customize the installation.
    

    Description

    I thought I'd introduce Typer via some small scripts where argparse is unwieldy. But having the autocompletion options in the command help scared the absolute crap out of a number of people: they assumed I was overengineering, that it would be complicated. Luckily you can suppress those, as I discovered by reading the source.

    (Working to bring the folks I scared around, because typer is an essential quality of life improvement for anyone using Python for pretty much anything.)

    Wanted Solution

    I'd like to see:

    1. add_completion default to False in typer.run. If you're doing the kind of program that warrants completion, you're probably using typer.Typer anyway.
    2. Some really minimal, sketchy documentation of the full API. There are other gems in there, eg, one thing people really liked that also isn't documented is no_args_is_help. People love that for ops scripts. Makes them feel safe. Come to think of it, I wish I could pass that to typer.run as well...

    I understand (1) is a big change and not do be taken lightly, and as I discovered in my description of (2) it brings up whether you should be able to pass other Typer options via run. But the first thing I did when I fired up typer for the first time is wonder, "can I suppress those completion options," searched the docs, and found nothing, so (2) would have solved my problem.

    I looked at main.py and run is simple as could be, so I could certainly make a PR for (1) if it's wanted. The instructions for contributing documentation look straightforward enough so I could take a crack at (2). That's a little more intimidating given the high standard of the documentation, but I could at least do a first draft.

    Wanted Code

    # in mycmd.py
    typer.run(main)
    
    # python mycmd.py --help
    #
    # *no completion options*
    

    Alternatives

    Minimally documenting the typer.Typer API. There's already an issue about documenting add_completion: https://github.com/tiangolo/typer/issues/141, why not do all of 'em?

    Operating System

    macOS

    Operating System Details

    No response

    Typer Version

    0.4.1

    Python Version

    Python 3.10.2

    Additional Context

    No response

    enhancement 
    opened by ajlive 13
  • [QUESTION] How to use Typer within Objects

    [QUESTION] How to use Typer within Objects

    Hello,

    I already used Typer for a few short CLIs but now I'd like to use it for a bigger, object-oriented project. I thought I find a way to use it correctly, but I'm getting errors related to the "self" argument.

    My code looks like this:

    main_menu.py

    class MainMenu:
        typer_app = typer.Typer()
        typer_app.add_typer(TournamentMenu.typer_app, name="tournament")
    
        def __init__(self):
            self.typer_app()
            self.tournament_handler = None
            self.print_menu()
            self.user_selection()
    
        def print_menu(self):
            number = typer.style("1. ", bold=True)
            typer.echo(number + "Tournois")
    
            number = typer.style("2. ", bold=True)
            typer.echo(number + "Gérer les joueurs")
    
        def user_selection(self):
            selection = typer.prompt("Entrez votre sélection: ")
            typer.echo("\n")
    
            if selection == "1":
                self.open_tournament_menu()
            else:
                self.user_selection()
    
        def open_tournament_menu(self):
            TournamentMenu()
    

    tournament_menu.py

    class TournamentMenu:
        typer_app = typer.Typer()
    
        def __init__(self):
            self.typer_app()
            self.print_menu()
            self.user_selection()
    
        def print_menu(self):
            number = typer.style("1. ", bold=True)
            typer.echo(number + "Commencer un nouveau tournoi")
    
            number = typer.style("2. ", bold=True)
            typer.echo(number + "Charger un tournoi")
    
        def user_selection(self):
            selection = typer.prompt("Entrez votre sélection: ")
    
            if selection == "1":
                self.create_new_tournament()
            else:
                self.user_selection()
    
        @typer_app.command("new")
        def create_new_tournament(self=None):
            NewTournamentMenu()
    

    new_tournament_menu.py

    class NewTournamentMenu:
        typer_app = typer.Typer()
    
        @typer_app.command()
        def __init__(self):
            self.typer_app()
            self.print_menu()
            self.user_selection()
    
        def print_menu(self):
            number = typer.style("1. ", bold=True)
            typer.echo(number + "Commencer un nouveau tournoi")
    
            number = typer.style("2. ", bold=True)
            typer.echo(number + "Charger un tournoi")
    
        def user_selection(self):
            selection = typer.prompt("Entrez votre sélection: ")
    
            if selection == "1":
                pass
            else:
                self.user_selection()
    

    But for example with python main.py tournament newI'm getting:

    Usage: dev.py [OPTIONS] SELF
    Try 'dev.py --help' for help.
    
    Error: Got unexpected extra argument (new)
    

    So, is it possible to use typer in this kind of object oriented situation ? What am I missing ?

    question 
    opened by PabloLec 13
  • Add click 8.1.0 support

    Add click 8.1.0 support

    Some deprecated code was removed in https://github.com/pallets/click/pull/2130 resulting in the failed import of get_terminal_size from click. Per the recommendation in Click's release notes, we can import from shutil instead.

    get_terminal_size can probably be dropped from Typer's interface in the future since it's been dropped from Click's, but I'll leave that decision to a future PR. This change is backwards compatible.

    See https://click.palletsprojects.com/en/8.1.x/changes/#version-8-1-0 Closes https://github.com/tiangolo/typer/issues/377

    opened by madkinsz 12
  • ⬆ [pre-commit.ci] pre-commit autoupdate

    ⬆ [pre-commit.ci] pre-commit autoupdate

    opened by pre-commit-ci[bot] 10
  • [QUESTION] How to add short option

    [QUESTION] How to add short option "-h" to "--help" callback

    First check

    • [x] I used the GitHub search to find a similar issue and didn't find it.
    • [x] I searched the Typer documentation, with the integrated search.
    • [x] I already searched in Google "How to X in Typer" and didn't find any information.
    • [x] I already searched in Google "How to X in Click" and didn't find any information.

    Description

    How can I add a short option "-h" to the existing "--help" callback?

    question 
    opened by JeromeK13 10
  • [QUESTION] using python-rich with Typer

    [QUESTION] using python-rich with Typer

    First check

    • [x] I used the GitHub search to find a similar issue and didn't find it.
    • [x] I searched the Typer documentation, with the integrated search.
    • [x] I already searched in Google "How to X in Typer" and didn't find any information.
    • [x] I already searched in Google "How to X in Click" and didn't find any information.

    Description

    How can I use python-rich with Typer ?

    Eg.

    from rich.console import Console
    
    console = Console()
    
    @app.command()
    def version() -> None:
        """Show project Version."""
        # typer.secho(f"project Version: {__version__}", fg=typer.colors.BRIGHT_GREEN)
    
        console.print(f"project Version: {__version__}", style="bold green")
    

    output:

    project Version: 0.0.1
    

    the problem that am facing is in test mode

    runner = CliRunner()
    
    def test_version_succeeds() -> None:
        """It exits with a status code of zero."""
        result = runner.invoke(app)
        assert result.exit_code == 0
        assert "project" in result.stdout
    

    output:

    FAILED tests/test_manage.py::test_version_succeeds - AssertionError: assert 'project' in ''
    

    So is there a way to make them work together ?

    question 
    opened by Mohamed-Kaizen 10
  • Support Python 3.10 optional union types

    Support Python 3.10 optional union types

    In Python 3.10+, recognise that SomeType | None is analogous to Optional[SomeType]. AFAIK, this shouldn't break anything pre-3.10 because it checks things via duck typing. Resolves #371.

    Instead of:

    from typing import Optional
    
    app = typer.Typer()
    
    @app.command()
    def command(option: Optional[str] = None, test: Optional[int] = typer.Option(None)):
      ...
    

    Allow:

    app = typer.Typer()
    
    @app.command()
    def command(option: str | None = None, test: int | None = typer.Option(None)):
      ...
    
    opened by potatoeggy 3
  • Accept environment variables named by convention when envvar is not set

    Accept environment variables named by convention when envvar is not set

    First Check

    • [X] I added a very descriptive title to this issue.
    • [X] I used the GitHub search to find a similar issue and didn't find it.
    • [X] I searched the Typer documentation, with the integrated search.
    • [X] I already searched in Google "How to X in Typer" and didn't find any information.
    • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
    • [X] I already checked if it is not related to Typer but to Click.

    Commit to Help

    • [X] I commit to help with one of those options 👆

    Example Code

    import typer
    
    cli = typer.Typer()
    
    @cli.command()
    def configure(file: str = typer.Argument("", envvar="FILE")):
        print("Configure could be written more succintly if envvar=FILE is created by convention")
    

    Description

    We usually define arguments and options as environment variables. We tipically use a simple convention where param becomes PARAM and some_param becomes SOME_PARAM. That adds a bit of boilerplate to method definitions. I would like typer to accept environment variables that match argument and options names by conventions.

    I can try to make a pull request if you find this behavior reasonable.

    Wanted Solution

    I would like that if envvar is not fullfilled in typer, it tries to get that environment variable by convention. I could try to make a pull request with this idea if you find it reasonable.

    Wanted Code

    import typer
    
    cli = typer.Typer()
    
    @cli.command()
    def configure(file: str)):
        print("Configure accepts FILE as envvar")
    

    Alternatives

    No response

    Operating System

    Linux

    Operating System Details

    No response

    Typer Version

    0.7.0

    Python Version

    Python 3.8.10

    Additional Context

    No response

    enhancement 
    opened by jruizaranguren 4
  • Default value for optional multi-value argument

    Default value for optional multi-value argument

    First Check

    • [X] I added a very descriptive title to this issue.
    • [X] I used the GitHub search to find a similar issue and didn't find it.
    • [X] I searched the Typer documentation, with the integrated search.
    • [X] I already searched in Google "How to X in Typer" and didn't find any information.
    • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
    • [X] I already checked if it is not related to Typer but to Click.

    Commit to Help

    • [X] I commit to help with one of those options 👆

    Example Code

    import typer
    
    def main(names: list[str] = typer.Argument(["Peter", "Paul", "Mary"])):
        for name in names:
            typer.echo(f"Hi, {name}")
    
    if __name__ == '__main__':
        typer.run(main)
    

    Description

    The provided example raises the following error:

    Traceback (most recent call last):
    
      File "[...]\main.py", line 8, in <module>
        typer.run(main)
    
    TypeError: 'default' is not supported for nargs=-1.
    

    Looking at the Click docs, my understanding is that nargs=-1 is used to denote Variadic arguments, i.e. multi-value arguments.

    So if default is not supported for nargs=-1, is there any way to have default values for multi-value arguments in Typer?

    Desired behaviour: the default values are used if no argument values are provided, with a help message that looks something like this:

    Usage: main.py [OPTIONS] [NAMES]...
    
    Arguments:
      [NAMES]...  [default: [Peter, Paul, Mary]]
    
    Options:
      --help  Show this message and exit.
    

    Operating System

    Windows

    Operating System Details

    No response

    Typer Version

    0.7.0

    Python Version

    3.10.9

    Additional Context

    I believe this is related to #108, where the conclusion was to use None as default to achieve an optional multi-value argument. However, it would be useful if other default values were supported as well. But this might just be a limitation of Click?

    Love the project ❤️

    question 
    opened by mathiazom 0
  • How to display commands grouped by category when running using `--help` argument

    How to display commands grouped by category when running using `--help` argument

    First Check

    • [x] I added a very descriptive title to this issue.
    • [X] I used the GitHub search to find a similar issue and didn't find it.
    • [X] I searched the Typer documentation, with the integrated search.
    • [X] I already searched in Google "How to X in Typer" and didn't find any information.
    • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
    • [X] I already checked if it is not related to Typer but to Click.

    Commit to Help

    • [X] I commit to help with one of those options 👆

    Example Code

    import typer
    
    
    # Troubleshooting and Debugging Commands:
    def describe(foo: str):
        print(f"{foo}")
    
    
    def logs(foo: str):
        print(f"{foo}")
    
    
    def attach(foo: str):
        print(f"{foo}")
    
    
    def _exec(foo: str):
        print(f"{foo}")
    
    
    def port_forward(foo: str):
        print(f"{foo}")
    
    
    def proxy(foo: str):
        print(f"{foo}")
    
    
    def cp(foo: str):
        print(f"{foo}")
    
    
    def auth(foo: str):
        print(f"{foo}")
    
    
    def debug(foo: str):
        print(f"{foo}")
    
    
    # Advanced Commands:
    def diff(foo: str):
        print(f"{foo}")
    
    
    def _apply(foo: str):
        print(f"{foo}")
    
    
    def patch(foo: str):
        print(f"{foo}")
    
    
    def replace(foo: str):
        print(f"{foo}")
    
    
    def wait(foo: str):
        print(f"{foo}")
    
    
    def kustomize(foo: str):
        print(f"{foo}")
    
    
    # Settings Commands:
    def label(foo: str):
        print(f"{foo}")
    
    
    def annotate(foo: str):
        print(f"{foo}")
    
    
    def completion(foo: str):
        print(f"{foo}")
    
    
    def main():
        # console = Console()
        app = typer.Typer()
    
        # Troubleshooting and Debugging Commands
        app.command(short_help="Show details of a specific resource or group of resources")(
            describe
        )
        app.command(short_help="Print the logs for a container in a pod")(logs)
        app.command(short_help="Attach to a running container")(attach)
        app.command("exec", short_help="Execute a command in a container")(_exec)
        app.command(short_help="Forward one or more local ports to a pod")(port_forward)
        app.command(short_help="Run a proxy to the Kubernetes API server")(proxy)
        app.command(short_help="Copy files and directories to and from containers")(cp)
        app.command(short_help="Inspect authorization")(auth)
        app.command(
            short_help="Create debugging sessions for troubleshooting workloads and nodes"
        )(debug)
    
        # Advanced
        app.command(short_help="Diff the live version against a would-be applied version")(
            diff
        )
        app.command("apply", short_help="Apply a configuration to a resource by file name or stdin")(
            _apply
        )
        app.command(short_help="Update fields of a resource")(patch)
        app.command(short_help="Replace a resource by file name or stdin")(replace)
        app.command(
            short_help="Experimental: Wait for a specific condition on one or many resources"
        )(wait)
        app.command(short_help="Build a kustomization target from a directory or URL")(
            kustomize
        )
    
        # Settings
        app.command(short_help="Update the labels on a resource")(label)
        app.command(short_help="Update the annotations on a resource")(annotate)
        app.command(
            short_help="Output shell completion code for the specified shell (bash, zsh, fish, or powershell"
        )(completion)
        app()
    
    
    if __name__ == "__main__":
        main()
    

    Description

    Hi, first of all let me tell you I've only been using typer for 20min and I love it, this is a really modern, powerful and very intuitive python package, so congrats about that :)

    I've got a question:

    • I'm trying to figure out how to achieve a similar behaviour to kubectl --help cli in a way that if run python my_typer_cli.py --help I'd be able to see all my commands grouped by categories. How can I achieve a similar behaviour using typer?

    Pasting the kubectl output:

    $ kubectl --help
    kubectl controls the Kubernetes cluster manager.
    
     Find more information at: https://kubernetes.io/docs/reference/kubectl/
    
    Basic Commands (Beginner):
      create          Create a resource from a file or from stdin
      expose          Take a replication controller, service, deployment or pod and expose it as a new
    Kubernetes service
      run             Run a particular image on the cluster
      set             Set specific features on objects
    
    Basic Commands (Intermediate):
      explain         Get documentation for a resource
      get             Display one or many resources
      edit            Edit a resource on the server
      delete          Delete resources by file names, stdin, resources and names, or by resources and
    label selector
    
    Deploy Commands:
      rollout         Manage the rollout of a resource
      scale           Set a new size for a deployment, replica set, or replication controller
      autoscale       Auto-scale a deployment, replica set, stateful set, or replication controller
    
    Cluster Management Commands:
      certificate     Modify certificate resources.
      cluster-info    Display cluster information
      top             Display resource (CPU/memory) usage
      cordon          Mark node as unschedulable
      uncordon        Mark node as schedulable
      drain           Drain node in preparation for maintenance
      taint           Update the taints on one or more nodes
    
    Troubleshooting and Debugging Commands:
      describe        Show details of a specific resource or group of resources
      logs            Print the logs for a container in a pod
      attach          Attach to a running container
      exec            Execute a command in a container
      port-forward    Forward one or more local ports to a pod
      proxy           Run a proxy to the Kubernetes API server
      cp              Copy files and directories to and from containers
      auth            Inspect authorization
      debug           Create debugging sessions for troubleshooting workloads and nodes
    
    Advanced Commands:
      diff            Diff the live version against a would-be applied version
      apply           Apply a configuration to a resource by file name or stdin
      patch           Update fields of a resource
      replace         Replace a resource by file name or stdin
      wait            Experimental: Wait for a specific condition on one or many resources
      kustomize       Build a kustomization target from a directory or URL.
    
    Settings Commands:
      label           Update the labels on a resource
      annotate        Update the annotations on a resource
      completion      Output shell completion code for the specified shell (bash, zsh, fish, or
    powershell)
    
    Other Commands:
      alpha           Commands for features in alpha
      api-resources   Print the supported API resources on the server
      api-versions    Print the supported API versions on the server, in the form of "group/version"
      config          Modify kubeconfig files
      plugin          Provides utilities for interacting with plugins
      version         Print the client and server version information
    
    Usage:
      kubectl [flags] [options]
    
    Use "kubectl <command> --help" for more information about a given command.
    Use "kubectl options" for a list of global command-line options (applies to all commands).
    

    Operating System

    Windows

    Operating System Details

    Windows 10 pro

    Typer Version

    0.7.0

    Python Version

    Python 3.10.1

    Additional Context

    No response

    question 
    opened by brupelo 1
  • Add rich print using _get_rich_console

    Add rich print using _get_rich_console

    This feature allows using rich's print in typer context.

    It uses the _get_rich_console to make it more aware of the terminal it sits in. For example, this can be useful if you want to set TERMINAL_WIDTH.

    opened by feluelle 6
Releases(0.7.0)
Owner
Sebastián Ramírez
Creator of FastAPI and Typer. Dev at @explosion. APIs, Deep Learning/ML, full-stack distributed systems, SQL/NoSQL, Python, Docker, JS, TypeScript, etc
Sebastián Ramírez
sane is a command runner made simple.

sane is a command runner made simple.

Miguel M. 22 Jan 03, 2023
Command line animations based on the state of the system

shell-emotions Command line animations based on the state of the system for Linux or Windows 10 The ascii animations were created using a modified ver

Simon Malave 63 Nov 12, 2022
Python library that measures the width of unicode strings rendered to a terminal

Introduction This library is mainly for CLI programs that carefully produce output for Terminals, or make pretend to be an emulator. Problem Statement

Jeff Quast 305 Dec 25, 2022
Python Command-line Application Tools

Clint: Python Command-line Interface Tools Clint is a module filled with a set of awesome tools for developing commandline applications. C ommand L in

Kenneth Reitz Archive 82 Dec 28, 2022
A simple terminal Christmas tree made with Python

Python Christmas Tree A simple CLI Christmas tree made with Python Installation Just clone the repository and run $ python terminal_tree.py More opti

Francisco B. 64 Dec 27, 2022
Rich is a Python library for rich text and beautiful formatting in the terminal.

Rich 中文 readme • lengua española readme • Läs på svenska Rich is a Python library for rich text and beautiful formatting in the terminal. The Rich API

Will McGugan 41.4k Jan 02, 2023
Library for building powerful interactive command line applications in Python

Python Prompt Toolkit prompt_toolkit is a library for building powerful interactive command line applications in Python. Read the documentation on rea

prompt-toolkit 8.1k Dec 30, 2022
Cement is an advanced Application Framework for Python, with a primary focus on CLI

Cement Framework Cement is an advanced Application Framework for Python, with a primary focus on Command Line Interfaces (CLI). Its goal is to introdu

Data Folk Labs, LLC 1.1k Dec 31, 2022
prompt_toolkit is a library for building powerful interactive command line applications in Python.

Python Prompt Toolkit prompt_toolkit is a library for building powerful interactive command line applications in Python. Read the documentation on rea

prompt-toolkit 8.1k Jan 04, 2023
CalcuPy 📚 Create console-based calculators in a few lines of code.

CalcuPy 📚 Create console-based calculators in a few lines of code. 📌 Installation pip install calcupy 📌 Usage from calcupy import Calculator calc

Dylan Tintenfich 7 Dec 01, 2021
Pythonic command line arguments parser, that will make you smile

docopt creates beautiful command-line interfaces Video introduction to docopt: PyCon UK 2012: Create *beautiful* command-line interfaces with Python N

7.7k Dec 30, 2022
Clint is a module filled with a set of awesome tools for developing commandline applications.

Clint: Python Command-line Interface Tools Clint is a module filled with a set of awesome tools for developing commandline applications. C ommand L in

Kenneth Reitz Archive 82 Dec 28, 2022
A thin, practical wrapper around terminal capabilities in Python

Blessings Coding with Blessings looks like this... from blessings import Terminal t = Terminal() print(t.bold('Hi there!')) print(t.bold_red_on_brig

Erik Rose 1.4k Jan 07, 2023
Typer, build great CLIs. Easy to code. Based on Python type hints.

Typer, build great CLIs. Easy to code. Based on Python type hints. Documentation: https://typer.tiangolo.com Source Code: https://github.com/tiangolo/

Sebastián Ramírez 10.1k Jan 02, 2023
Python and tab completion, better together.

argcomplete - Bash tab completion for argparse Tab complete all the things! Argcomplete provides easy, extensible command line tab completion of argum

Andrey Kislyuk 1.1k Jan 08, 2023
Humane command line arguments parser. Now with maintenance, typehints, and complete test coverage.

docopt-ng creates magic command-line interfaces CHANGELOG New in version 0.7.2: Complete MyPy typehints - ZERO errors. Required refactoring class impl

Jazzband 108 Dec 27, 2022
A module for parsing and processing commands.

cmdtools A module for parsing and processing commands. Installation pip install --upgrade cmdtools-py install latest commit from GitHub pip install g

1 Aug 14, 2022
emoji terminal output for Python

Emoji Emoji for Python. This project was inspired by kyokomi. Example The entire set of Emoji codes as defined by the unicode consortium is supported

Taehoon Kim 1.6k Jan 02, 2023
Python composable command line interface toolkit

$ click_ Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary. It's the "Comm

The Pallets Projects 13.3k Dec 31, 2022
A fast, stateless http slash commands framework for scale. Built by the Crunchy bot team.

Roid 🤖 A fast, stateless http slash commands framework for scale. Built by the Crunchy bot team. 🚀 Installation You can install roid in it's default

Harrison Burt 7 Aug 09, 2022