{"owner":"fastapi","repo":"typer","hasSkills":true,"totalSkillsCount":9,"totalTokensCount":13893,"categories":["command-prompt","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["docs/tutorial/commands/arguments.md","docs/tutorial/commands/options.md","docs/tutorial/commands/name.md","docs/tutorial/commands/context.md","docs/tutorial/commands/callback.md","docs/tutorial/commands/one-or-multiple.md","typer/.agents/skills/typer/SKILL.md","docs/tutorial/commands/index.md","docs/tutorial/commands/help.md"],"skills":{"docs/tutorial/commands/arguments.md":"# Command CLI Arguments\n\nThe same way as with a CLI application with a single command, subcommands (or just \"commands\") can also have their own *CLI arguments*:\n\n{* docs_src/commands/arguments/tutorial001_py310.py hl[7,12] *}\n\n<div class=\"termy\">\n\n```console\n// Check the help for create\n$ uv run python main.py create --help\n\nUsage: main.py create [OPTIONS] {username}\n\nArguments:\n  username  [required]\n\nOptions:\n  --help  Show this message and exit.\n\n// Call it with a CLI argument\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// The same for delete\n$ uv run python main.py delete Camila\n\nDeleting user: Camila\n```\n\n</div>\n\n/// tip\n\nEverything to the *right* of the *command* are *CLI parameters* (*CLI arguments* and *CLI options*) for that command.\n\n///\n\n/// note | Technical Details\n\nActually, it's everything to the right of that command, *before any subcommand*.\n\nIt's possible to have groups of *subcommands*, it's like if one *command* also had *subcommands*. And then those *subcommands* could have their own *CLI parameters*, taking their own *CLI parameters*.\n\nYou will see about them later in another section.\n\n///\n","docs/tutorial/commands/options.md":"# Command CLI Options\n\nCommands can also have their own *CLI options*.\n\nIn fact, each command can have different *CLI arguments* and *CLI options*:\n\n{* docs_src/commands/options/tutorial001_an_py310.py hl[9,15:18,28:30,39] *}\n\nHere we have multiple commands, with different *CLI parameters*:\n\n* `create`:\n    * `username`: a *CLI argument*.\n* `delete`:\n    * `username`: a *CLI argument*.\n    * `--force`: a *CLI option*, if not provided, it's prompted.\n* `delete-all`:\n    * `--force`: a *CLI option*, if not provided, it's prompted.\n* `init`:\n    * Doesn't take any *CLI parameters*.\n\n<div class=\"termy\">\n\n```console\n// Check the help\npython main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n  delete-all\n  init\n```\n\n</div>\n\n/// tip\n\nCheck the command `delete-all`, by default command names are generated from the function name, replacing `_` with `-`.\n\n///\n\nTest it:\n\n<div class=\"termy\">\n\n```console\n// Check the command create\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// Now test the command delete\n$ uv run python main.py delete Camila\n\n# Are you sure you want to delete the user? [y/n]: $ y\n\nDeleting user: Camila\n\n$ uv run python main.py delete Wade\n\n# Are you sure you want to delete the user? [y/n]: $ n\n\nOperation cancelled\n\n// And finally, the command delete-all\n// Notice it doesn't have CLI arguments, only a CLI option\n\n$ uv run python main.py delete-all\n\n# Are you sure you want to delete ALL users? [y/n]: $ y\n\nDeleting all users\n\n$ uv run python main.py delete-all\n\n# Are you sure you want to delete ALL users? [y/n]: $ n\n\nOperation cancelled\n\n// And if you pass the --force CLI option, it doesn't need to confirm\n\n$ uv run python main.py delete-all --force\n\nDeleting all users\n\n// And init that doesn't take any CLI parameter\n$ uv run python main.py init\n\nInitializing user database\n```\n\n</div>\n","docs/tutorial/commands/name.md":"# Custom Command Name\n\nBy default, the command names are generated from the function name.\n\nSo, if your function is something like:\n\n```Python\ndef create(username: str): ...\n```\n\nThen the command name will be `create`.\n\nBut if you already had a function called `create()` somewhere in your code, you would have to name your CLI function differently.\n\nAnd what if you wanted the command to still be named `create`?\n\nFor this, you can set the name of the command in the first parameter for the `@app.command()` decorator:\n\n{* docs_src/commands/name/tutorial001_py310.py hl[6,11] *}\n\nNow, even though the functions are named `cli_create_user()` and `cli_delete_user()`, the commands will still be named `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test it\n$ uv run python main.py create Camila\n\nCreating user: Camila\n```\n\n</div>\n\nNote that any underscores in the function name will be replaced with dashes.\n\nSo if your function is something like:\n\n```Python\ndef create_user(username: str): ...\n```\nThen the command name will be `create-user`.\n","docs/tutorial/commands/context.md":"# Using the Context\n\nWhen you create a **Typer** application it always has a special, hidden object underneath called the \"Context\".\n\nBut you can access the context by declaring a function parameter of type `typer.Context`.\n\nYou might have read it in [CLI Option Callback and Context](../options/callback-and-context.md).\n\nThe same way, in commands or in the main `Typer` callback you can access the context by declaring a function parameter of type `typer.Context`.\n\n## Getting the context\n\nFor example, let's say that you want to execute some logic in a `Typer` callback depending on the subcommand that is being called.\n\nYou can get the name of the subcommand from the context:\n\n{* docs_src/commands/context/tutorial001_py310.py hl[17,21] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\n// We get the message from the callback\nAbout to execute command: create\nCreating user: Camila\n\n$ uv run python main.py delete Camila\n\n// We get the message from the callback, this time with delete\nAbout to execute command: delete\nDeleting user: Camila\n```\n\n</div>\n\n## Executable callback\n\nBy default, the callback is only executed right before executing a command.\n\nAnd if no command is provided, the help message is shown.\n\nBut we could make it run even without a subcommand with `invoke_without_command=True`:\n\n{* docs_src/commands/context/tutorial002_py310.py hl[16] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py\n\n// The callback is executed, we don't get the default help message\nInitializing database\n\n// Try with a command\n$ uv run python main.py create Camila\n\n// The callback is still executed\nInitializing database\nCreating user: Camila\n```\n\n</div>\n\n## Exclusive executable callback\n\nWe might not want the callback to be executed if there's already other command that will be executed.\n\nFor that, we can get the `typer.Context` and check if there's an invoked command in `ctx.invoked_subcommand`.\n\nIf it's `None`, it means that we are not calling a subcommand but the main program (the callback) directly:\n\n{* docs_src/commands/context/tutorial003_py310.py hl[17,21] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py\n\n// The callback is executed\nInitializing database\n\n// Check it with a subcommand\n$ uv run python main.py create Camila\n\n// This time the callback is not executed\nCreating user: Camila\n```\n\n</div>\n\n## Configuring the context\n\nYou can pass configurations for the context when creating a command or callback.\n\nFor example, you could keep additional *CLI parameters* not declared in your CLI program with `ignore_unknown_options` and `allow_extra_args`.\n\nThen you can access those extra raw *CLI parameters* as a `list` of `str` in `ctx.args`:\n\n{* docs_src/commands/context/tutorial004_py310.py hl[7,9,10] *}\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --name Camila --city Berlin\n\nGot extra arg: --name\nGot extra arg: Camila\nGot extra arg: --city\nGot extra arg: Berlin\n```\n\n</div>\n\n/// tip\n\nNotice that it saves all the extra *CLI parameters* as a raw `list` of `str`, including the *CLI option* names and values, everything together.\n\n///\n","docs/tutorial/commands/callback.md":"# Typer Callback\n\nWhen you create an `app = typer.Typer()` it works as a group of commands.\n\nAnd you can create multiple commands with it.\n\nEach of those commands can have their own *CLI parameters*.\n\nBut as those *CLI parameters* are handled by each of those commands, they don't allow us to create *CLI parameters* for the main CLI application itself.\n\nBut we can use `@app.callback()` for that.\n\nIt's very similar to `@app.command()`, but it declares the *CLI parameters* for the main CLI application (before the commands):\n\n{* docs_src/commands/callback/tutorial001_py310.py hl[25,26,27,28,29,30,31,32] *}\n\nHere we create a `callback` with a `--verbose` *CLI option*.\n\n/// tip\n\nAfter getting the `--verbose` flag, we modify a global `state`, and we use it in the other commands.\n\nThere are other ways to achieve the same, but this will suffice for this example.\n\n///\n\nAnd as we added a docstring to the callback function, by default it will be extracted and used as the help text.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice the main help text, extracted from the callback function: \"Manage users in the awesome CLI app.\"\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Manage users in the awesome CLI app.\n\nOptions:\n  --verbose / --no-verbose  [default: no-verbose]\n  --install-completion      Install completion for the current shell.\n  --show-completion         Show completion for the current shell, to copy it or customize the installation.\n  --help                    Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Check the new top level CLI option --verbose\n\n// Try it normally\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// And now with --verbose\n$ uv run python main.py --verbose create Camila\n\nWill write verbose output\nAbout to create a user\nCreating user: Camila\nJust created a user\n\n// Notice that --verbose belongs to the callback, it has to go before create or delete ⛔️\n$ uv run python main.py create --verbose Camila\n\nUsage: main.py create [OPTIONS] {username}\nTry \"main.py create --help\" for help.\n\nError: No such option: --verbose\n```\n\n</div>\n\n## Adding a callback on creation\n\nIt's also possible to add a callback when creating the `typer.Typer()` app:\n\n{* docs_src/commands/callback/tutorial002_py310.py hl[4,5,8] *}\n\nThat achieves the same as with `@app.callback()`.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\nRunning a command\nCreating user: Camila\n```\n\n</div>\n\n## Overriding a callback\n\nIf you added a callback when creating the `typer.Typer()` app, it's possible to override it with `@app.callback()`:\n\n{* docs_src/commands/callback/tutorial003_py310.py hl[11,12,13] *}\n\nNow `new_callback()` will be the one used.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\n// Notice that the message is the one from new_callback()\nOverride callback, running a command\nCreating user: Camila\n```\n\n</div>\n\n## Adding a callback only for documentation\n\nYou can also add a callback just to add the documentation in the docstring.\n\nIt can be convenient especially if you have several lines of text, as the indentation will be automatically handled for you:\n\n{* docs_src/commands/callback/tutorial004_py310.py hl[8,9,10,11,12,13,14,15,16] *}\n\nNow the callback will be used mainly to extract the docstring for the help text.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n// Notice all the help text extracted from the callback docstring\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Manage users CLI app.\n\n  Use it with the create command.\n\n  A new user with the given 'name' will be created.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// And it just works as normally\n$ uv run python main.py create Camila\n\nCreating user: Camila\n```\n\n</div>\n","docs/tutorial/commands/one-or-multiple.md":"# One or Multiple Commands\n\nYou might have noticed that if you create a single command, as in the following example:\n\n{* docs_src/typer_app/tutorial001_py310.py hl[3,6,12] *}\n\n**Typer** is smart enough to create a CLI application with that single function as the main CLI application, not as a command/subcommand:\n\n<div class=\"termy\">\n\n```console\n// Without a CLI argument\n$ uv run python main.py\n\nUsage: main.py [OPTIONS] {name}\nTry \"main.py --help\" for help.\n\nError: Missing argument 'name'.\n\n// With the 'name' CLI argument\n$ uv run python main.py Camila\n\nHello Camila\n\n// Asking for help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] {name}\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n```\n\n</div>\n\n/// tip\n\nNotice that it doesn't show a command `main`, even though the function name is `main`.\n\n///\n\nBut if you add multiple commands, **Typer** will create one *CLI command* for each one of them:\n\n{* docs_src/commands/index/tutorial002_py310.py hl[6,11] *}\n\nHere we have 2 commands `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test the commands\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n\n$ uv run python main.py delete\n\nDeleting user: Hiro Hamada\n```\n\n</div>\n\n## One command and one callback\n\nIf you want to create a CLI app with one single command but you still want it to be a command/subcommand you can just add a callback:\n\n{* docs_src/commands/one_or_multiple/tutorial001_py310.py hl[11,12,13] *}\n\nAnd now your CLI program will have a single command.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice the single command create\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// Try it\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n```\n\n</div>\n\n## Using the callback to document\n\nNow that you are using a callback just to have a single command, you might as well use it to add documentation for your app:\n\n{* docs_src/commands/one_or_multiple/tutorial002_py310.py hl[11,12,13,14,15,16,17] *}\n\nAnd now the docstring from the callback will be used as the help text:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n// Notice the help text from the docstring\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Creates a single user Hiro Hamada.\n\n  In the next version it will create 5 more users.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// And it still works the same, the callback does nothing\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n```\n\n</div>\n","typer/.agents/skills/typer/SKILL.md":"---\nname: typer\ndescription: Typer best practices and conventions. Use when working with Typer CLIs. Keeps Typer code clean and up to date with the latest features and patterns, updated with new versions. Write new code or refactor and update old code.\n---\n\n# Typer\n\nOfficial Typer skill to write code with best practices, keeping up to date with new versions and features.\n\n## Installing typer\n\nIn a virtual environment, `pip install typer` (with pip) or `uv pip install typer` (with uv). For your library/project, add `typer` to the dependencies in `pyproject.toml`.\n\nDo not install `typer-slim` or `typer-cli`, they are both deprecated and will now simply install `typer`.\n\nTyper supports Python 3.10 and above.\n\n## Use an explicit `Typer` app\n\nFor maximum generalizability, create an explicit Typer app and register subcommand(s), instead of using `typer.run`:\n\n```python\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef hello():\n    print(f\"Hello World\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\ninstead of:\n\n```python\n# DO NOT DO THIS: Not extensible. Use Typer() instead.\nimport typer\n\n\ndef main():\n    print(f\"Hello World\")\n\n\nif __name__ == \"__main__\":\n    typer.run(main)\n```\n\n## Execute the app\n\nTo execute the app in the terminal, run\n\n```bash\npython main.py\n```\n\nWhen multiple commands are registered to the Typer app, you have to add the command name:\n\n```bash\npython main.py hello\n```\n\nTo see the automatically generated help documentation, run\n\n```bash\npython main.py --help\n```\n\nor set `no_args_is_help` to `True` when creating the `Typer()` add to automatically show the help when running a command without any arguments.\n\n## Use `Annotated`\n\nAlways prefer the `Annotated` style for declarations of CLI arguments and options.\n\nIt allows us to pass additional metadata that can be used by Typer.\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef hello(name: Annotated[str, typer.Argument()] = \"World\"):\n    # Note that name is an optional Argument, as a default is provided\n    print(f\"Hello {name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nThis program can be run as-is, or can provide a specific name:\n\n```bash\npython main.py\npython main.py Rick\n```\n\nAn older way of setting a default value is this:\n```python\n# DO NOT DO THIS: old style. Use Annotated instead.\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=\"World\")):\n    # Note that name is an optional Argument, as a default is provided\n    print(f\"Hello {name}\")\n```\n\nSimilarly, the old style could use ellipsis (...) to explicitly mark an argument as required.\n\n```python\n# DO NOT DO THIS: old style. Use Annotated without a default value instead.\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=...)):\n    # Note that name is now a required Argument\n    print(f\"Hello {name}\")\n```\n\n## CLI Options\n\nCLI options are declared in a similar fashion as arguments, but will be called on the CLI with a single dash (single letter) or 2 dashes (full name).\n\nThe CLI option name is automatically generated from the variable name, so `user_name` becomes `--user-name` automatically:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user_name: Annotated[str, typer.Option()]):\n    # On the CLI, the required user name can be specified with --user-name\n    print(f\"Hello {user_name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nIf you want to specify a different name, or want to add a short version, declare them in the `typer.Option`:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user_name: Annotated[str, typer.Option(\"--name\", \"-n\")]):\n    # On the CLI, the required user name can be specified with -n or --name\n    print(f\"Hello {user_name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nYou can run this program as such:\n\n```bash\npython main.py -n \"Rick\"\npython main.py --name \"Morty\"\n```\n\n### CLI options with multiple values\n\nBy declaring a CLI option as a list, it can receive multiple values:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user: Annotated[list[str] | None, typer.Option()] = None):\n    if not user:\n        print(f\"No users provided!\")\n        raise typer.Abort()\n    for u in user:\n        print(f\"Processing user: {u}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nThis can be executed like so:\n\n```bash\npython main.py --user Rick --user Morty --user Summer\n```\n\n## Rich\n\nBy default, Rich can be used with its custom markup syntax to set colors and styles, e.g.\n\n```python\nfrom rich import print\n\nprint(\"[bold red]Alert![/bold red] [green]Portal gun[/green] shooting! :boom:\")\n```\n\nTyper supports using Rich formatting in the docstrings and the help messages of CLI arguments and CLI options.\n\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be [green]created[/green]\")\n    ],\n):\n    \"\"\"\n    [bold green]Create[/bold green] a new [italic]shiny[/italic] user. :sparkles:\n\n    This requires a [underline]username[/underline].\n    \"\"\"\n    print(f\"Creating user: {username}\")\n\n\n@app.command(help=\"[bold red]Delete[/bold red] a user with [italic]username[/italic].\")\ndef delete(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be [red]deleted[/red]\")\n    ],\n):\n    \"\"\"\n    Some internal utility function to delete.\n    \"\"\"\n    print(f\"Deleting user: {username}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nTo disable Rich formatting, set `rich_markup_mode` to `None` when creating a `Typer()` app. By default (when no value is given), Rich formatting is enabled.\n\n### Rich markdown\n\nYou can also set `rich_markup_mode` to `\"markdown\"` to use Markdown in the docstring:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"markdown\")\n\n\n@app.command(help=\"**Delete** a user with *username*.\")\ndef delete(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be **deleted** :boom:\")\n    ],\n):\n    print(f\"Deleting user: {username}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\n## Click\n\nOriginally, Typer was built on Click. However, since version 0.26.0, Typer has vendored Click. As such, Click extensions should not be used anymore.\n\nOther settings of `Option` and `Argument` that came from Click but shouldn't be used in Typer anymore, include: `expose_value`, `shell_complete`, `show_choices`, `errors`, `prompt_required`, `is_flag`, `flag_value` and `allow_from_autoenv`.\n\nCode bases using these should be refactored to use pure Typer functionality.\n","docs/tutorial/commands/index.md":"# Commands\n\nWe have seen how to create a CLI program with possibly several *CLI options* and *CLI arguments*.\n\nBut **Typer** allows you to create CLI programs with several commands (also known as subcommands).\n\nFor example, the program `git` has several commands.\n\nOne command of `git` is `git push`. And `git push` in turn takes its own *CLI arguments* and *CLI options*.\n\nFor example:\n\n<div class=\"termy\">\n\n```console\n// The push command with no parameters\n$ git push\n\n---> 100%\n\n// The push command with one CLI option --set-upstream and 2 CLI arguments\n$ git push --set-upstream origin master\n\n---> 100%\n```\n\n</div>\n\nAnother command of `git` is `git pull`, it also has some *CLI parameters*.\n\nIt's like if the same big program `git` had several small programs inside.\n\n/// tip\n\nA command looks the same as a *CLI argument*, it's just some name without a preceding `--`. But commands have a predefined name, and are used to group different sets of functionalities into the same CLI application.\n\n///\n\n## Command or subcommand\n\nIt's common to call a CLI program a \"command\".\n\nBut when one of these programs have subcommands, those subcommands are also frequently called just \"commands\".\n\nHave that in mind so you don't get confused.\n\nHere I'll use **CLI application** or **program** to refer to the program you are building in Python with Typer, and **command** to refer to one of these \"subcommands\" of your program.\n\n## A CLI application with multiple commands\n\n**Typer** allows creating CLI applications with multiple commands/subcommands.\n\nNow that you know how to create an explicit `typer.Typer()` application and add one command, let's see how to add multiple commands.\n\nLet's say that we have a CLI application to manage users.\n\nWe'll have a command to `create` users and another command to `delete` them.\n\nTo begin, let's say it can only create and delete one single predefined user:\n\n{* docs_src/commands/index/tutorial002_py310.py hl[6,11] *}\n\nNow we have a CLI application with 2 commands, `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test them\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n\n$ uv run python main.py delete\n\nDeleting user: Hiro Hamada\n\n// Now we have 2 commands! 🎉\n```\n\n</div>\n\nNotice that the help text now shows the 2 commands: `create` and `delete`.\n\n/// tip\n\nBy default, the names of the commands are generated from the function name.\n\n///\n\n## Show the help message if no command is given\n\nBy default, we need to specify `--help` to get the command's help page.\n\nHowever, by setting `no_args_is_help=True` when defining the `typer.Typer()` application, the help function will be shown whenever no argument is given:\n\n{* docs_src/commands/index/tutorial003_py310.py hl[3] *}\n\nNow we can run this:\n\n<div class=\"termy\">\n\n```console\n// Check the help without having to type --help\n$ uv run python main.py\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n```\n\n</div>\n\n\n## Sorting of the commands\n\nNote that by design, **Typer** shows the commands in the order they've been declared.\n\nSo, if we take our original example, with `create` and `delete` commands, and reverse the order in the Python file:\n\n{* docs_src/commands/index/tutorial004_py310.py hl[7,12] *}\n\nThen we will see the `delete` command first in the help output:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  delete\n  create\n```\n\n</div>\n\n## Decorator Technical Details\n\nWhen you use `@app.command()` the function under the decorator is registered in the **Typer** application and is then used later by the application.\n\nBut Typer doesn't modify that function itself, the function is left as is.\n\nThat means that if your function is simple enough that you could create it without using `typer.Option()` or `typer.Argument()`, you could use the same function for a **Typer** application and a **FastAPI** application putting both decorators on top, or similar tricks.\n","docs/tutorial/commands/help.md":"# Command Help\n\nThe same as before, you can add help for the commands in the docstrings and the *CLI options*.\n\nAnd the `typer.Typer()` application receives a parameter `help` that you can pass with the main help text for your CLI program:\n\n{* docs_src/commands/help/tutorial001_an_py310.py hl[5,10:12,23,27:31,44,48:52,61:63] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the new help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Awesome CLI user manager.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create      Create a new user with username.\n  delete      Delete a user with username.\n  delete-all  Delete ALL users in the database.\n  init        Initialize the users database.\n\n// Now the commands have inline help 🎉\n\n// Check the help for create\n$ uv run python main.py create --help\n\nUsage: main.py create [OPTIONS] {username}\n\n  Create a new user with username.\n\nArguments:\n  username  [required]\n\nOptions:\n  --help  Show this message and exit.\n\n// Check the help for delete\n$ uv run python main.py delete --help\n\nUsage: main.py delete [OPTIONS] {username}\n\n  Delete a user with username.\n\n  If --force is not used, will ask for confirmation.\n\nArguments:\n  username  [required]\n\nOptions:\n  --force / --no-force  Force deletion without confirmation.  [required]\n  --help                Show this message and exit.\n\n// Check the help for delete-all\n$ uv run python main.py delete-all --help\n\nUsage: main.py delete-all [OPTIONS]\n\n  Delete ALL users in the database.\n\n  If --force is not used, will ask for confirmation.\n\nOptions:\n  --force / --no-force  Force deletion without confirmation.  [required]\n  --help                Show this message and exit.\n\n// Check the help for init\n$ uv run python main.py init --help\n\nUsage: main.py init [OPTIONS]\n\n  Initialize the users database.\n\nOptions:\n  --help  Show this message and exit.\n```\n\n</div>\n\n/// tip\n\n`typer.Typer()` receives several other parameters for other things, we'll see that later.\n\nYou will also see how to use \"Callbacks\" later, and those include a way to add this same help message in a function docstring.\n\n///\n\n## Overwrite command help\n\nYou will probably be better adding the help text as a docstring to your functions, but if for some reason you wanted to overwrite it, you can use the `help` function argument passed to `@app.command()`:\n\n{* docs_src/commands/help/tutorial002_py310.py hl[6,14] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice it uses the help passed to @app.command()\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy\n                        it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create  Create a new user with username.\n  delete  Delete a user with username.\n\n// It uses \"Create a new user with username.\" instead of \"Some internal utility function to create.\"\n```\n\n</div>\n\n## Deprecate a Command\n\nThere could be cases where you have a command in your app that you need to deprecate, so that your users stop using it, even while it's still supported for a while.\n\nYou can mark it with the parameter `deprecated=True`:\n\n{* docs_src/commands/help/tutorial003_py310.py hl[14] *}\n\nAnd when you show the `--help` option you will see it's marked as \"`deprecated`\":\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                  </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create       </b></font> Create a user.                                      │\n<font color=\"#A5A5A1\">│ </font><font color=\"#6B9F98\"><b>delete       </b></font> Delete a user.              <font color=\"#F92672\">(deprecated)           </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd if you check the `--help` for the deprecated command (in this example, the command `delete`), it also shows it as deprecated:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                  </b>\n<b>                                                                     </b>\n <font color=\"#F92672\">(deprecated) </font>\n Delete a user.\n This is deprecated and will stop being supported soon.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  <font color=\"#A6194C\">[required]</font>                              │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n## Suggest Commands\n\nAs of version 0.20.0, Typer added support for suggesting mistyped command names. This feature is **enabled by default**, but you can disable it with the parameter `suggest_commands=False`:\n\n{* docs_src/commands/index/tutorial005_py310.py hl[3] *}\n\nIf a user mistypes a command, they'll see a helpful suggestion:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py crate\n\n<font color=\"#C4A000\">Usage: </font>main.py [OPTIONS] COMMAND [ARGS]...\n<font color=\"#AAAAAA\">Try </font><font color=\"#22436D\">&apos;main.py </font><font color=\"#4C6A8A\"><b>--help</b></font><font color=\"#22436D\">&apos;</font><font color=\"#AAAAAA\"> for help.</font>\n<font color=\"#CC0000\">╭─ Error ───────────────────────────────────────────────────────────╮</font>\n<font color=\"#CC0000\">│</font> No such command &apos;crate&apos;. Did you mean &apos;create&apos;?                   <font color=\"#CC0000\">│</font>\n<font color=\"#CC0000\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nIf there are multiple close matches, Typer will suggest them all. This feature uses Python's built-in `difflib.get_close_matches()` to find similar command names, making your CLI more user-friendly by helping users recover from typos.\n\n## Rich Markdown and Markup\n\nTyper installs **Rich** to allow for more formatting in the docstrings and the `help` parameter for *CLI arguments* and *CLI options*. You will see more about it below. 👇\n\n/// note\n\nYou can disable rich text formatting by setting `rich_markup_mode` to `None` for your specific app.\nAlternatively, you can disable it globally using an environmental variable `TYPER_USE_RICH` set to `False` or `0`.\n\n///\n\n### Rich Markup\n\nIf you set `rich_markup_mode=\"rich\"` when creating the `typer.Typer()` app (which is the default), you will be able to use [Rich Console Markup](https://rich.readthedocs.io/en/stable/markup.html) in the docstring, and even in the help for the *CLI arguments* and options:\n\n{* docs_src/commands/help/tutorial004_an_py310.py hl[5,11,15:17,22,25,28] *}\n\nWith that, you can use [Rich Console Markup](https://rich.readthedocs.io/en/stable/markup.html) to format the text in the docstring for the command `create`, make the word \"`create`\" bold and green, and even use an [emoji](https://rich.readthedocs.io/en/stable/markup.html#emoji).\n\nYou can also use markup in the help for the `username` CLI Argument.\n\nAnd the same as before, the help text overwritten for the command `delete` can also use Rich Markup, the same in the CLI Argument and CLI Option.\n\nIf you run the program and check the help, you will see that **Typer** uses **Rich** internally to format the help.\n\nCheck the help for the `create` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username}                   </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\"><b>Create</b></font> a new <i>shiny</i> user. ✨\n This requires a <font color=\"#A5A5A1\"><u style=\"text-decoration-style:single\">username</u></font><font color=\"#A5A5A1\">.                                           </font>\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <font color=\"#A6E22E\">created</font>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                </font>               │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd check the help for the `delete` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <font color=\"#F92672\"><b>Delete</b></font> a user with <i>username</i>.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <font color=\"#F92672\">deleted</font>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                </font>               │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the <font color=\"#F92672\"><b>deletion</b></font> 💥                  │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n### Rich Markdown\n\nIf you set `rich_markup_mode=\"markdown\"` when creating the `typer.Typer()` app, you will be able to use Markdown in the docstring:\n\n{* docs_src/commands/help/tutorial005_an_py310.py hl[5,10,13:21,26,28:29] *}\n\nWith that, you can use Markdown to format the text in the docstring for the command `create`, make the word \"`create`\" bold, show a list of items, and even use an [emoji](https://rich.readthedocs.io/en/stable/markup.html#emoji).\n\nAnd the same as before, the help text overwritten for the command `delete` can also use Markdown.\n\nCheck the help for the `create` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <b>Create</b> a new <i>shiny</i> user. ✨\n\n <font color=\"#F4BF75\"><b> • </b></font><font color=\"#A5A5A1\">Create a username                                                </font>\n <font color=\"#F4BF75\"><b> • </b></font><font color=\"#A5A5A1\">Show that the username is created                                </font>\n\n <font color=\"#F4BF75\">───────────────────────────────────────────────────────────────────</font>\n Learn more at the <font color=\"#44919F\">Typer docs website</font>\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <b>created</b>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                              </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd the same for the `delete` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <b>Delete</b> a user with <i>username</i>.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <b>deleted</b>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                              </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the <b>deletion</b> 💥                  │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n/// note\n\nNotice that in Markdown you cannot define colors. For colors you might prefer to use Rich markup.\n\n///\n\n## Help Panels\n\nIf you have many commands or CLI parameters, you might want to show their documentation in different panels when using the `--help` option.\n\nIf you installed [Rich](https://rich.readthedocs.io/) as described in [Printing and Colors](../printing.md), you can configure the panel to use for each command or CLI parameter.\n\n### Help Panels for Commands\n\nTo set the panel for a command you can pass the argument `rich_help_panel` with the name of the panel you want to use:\n\n{* docs_src/commands/help/tutorial006_py310.py hl[22,30,38,46] *}\n\nCommands without a panel will be shown in the default panel `Commands`, and the rest will be shown in the next panels:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                   </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create          </b></font> <font color=\"#A6E22E\">Create</font> a new user. ✨                            │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>delete          </b></font> <font color=\"#F92672\">Delete</font> a user. ❌                                │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Utils and Configs ───────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>config  </b></font> <font color=\"#66D9EF\">Configure</font> the system. ⚙                                 │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>sync    </b></font> <font color=\"#66D9EF\">Synchronize</font> the system or something fancy like that. ♻  │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Help and Others ─────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>help         </b></font> Get <font color=\"#F4BF75\">help</font> with the system. ❓                        │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>report       </b></font> <font color=\"#F4BF75\">Report</font> an issue. ❗                                 │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n### Help Panels for CLI Parameters\n\nThe same way, you can configure the panels for *CLI arguments* and *CLI options* with `rich_help_panel`.\n\nAnd of course, in the same application you can also set the `rich_help_panel` for commands.\n\n{* docs_src/commands/help/tutorial007_an_py310.py hl[14,20,26,36] *}\n\nThen if you run the application you will see all the *CLI parameters* in their respective panels.\n\n* First the ***CLI arguments*** that don't have a panel name set in a **default** one named \"`Arguments`\".\n* Next the ***CLI arguments*** with a **custom panel**. In this example named \"`Secondary Arguments`\".\n* After that, the ***CLI options*** that don't have a panel in a **default** one named \"`Options`\".\n* And finally, the ***CLI options*** with a **custom panel** set. In this example named \"`Additional Data`\".\n\nYou can check the `--help` option for the command `create`:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username} [lastname]          </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\">Create</font> a new user. ✨\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to create                  │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]            </font>                   │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Secondary Arguments ─────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│   lastname      </font><font color=\"#A37F4E\"><b>lastname</b></font>  The last name of the new user           │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the creation of the user         │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Additional Data ─────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--age</b></font>                   <font color=\"#F4BF75\"><b>&lt;int&gt;   </b></font>  The age of the new user         │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--favorite-color</b></font>        <font color=\"#F4BF75\"><b>&lt;str&gt;   </b></font>  The favorite color of the new   │\n<font color=\"#A5A5A1\">│                                  user                             │</font>\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd of course, the `rich_help_panel` can be used in the same way for commands in the same application.\n\nAnd those panels will be shown when you use the main `--help` option.\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                   </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create          </b></font> <font color=\"#A6E22E\">Create</font> a new user. ✨                            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Utils and Configs ───────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>config         </b></font> <font color=\"#66D9EF\">Configure</font> the system. ⚙                          │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nYou can see the custom panel for the commands for \"`Utils and Configs`\".\n\n## Epilog\n\nIf you need, you can also add an epilog section to the help of your commands:\n\n{* docs_src/commands/help/tutorial008_py310.py hl[6] *}\n\nAnd when you check the `--help` option it will look like:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] {username}                            </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\">Create</font> a new user. ✨\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>                  <font color=\"#A6194C\">[required]</font>              │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n\n Made with ❤ in <font color=\"#66D9EF\">Venus</font>\n```\n\n</div>\n"},"files":{"docs/tutorial/commands/arguments.md":"# Command CLI Arguments\n\nThe same way as with a CLI application with a single command, subcommands (or just \"commands\") can also have their own *CLI arguments*:\n\n{* docs_src/commands/arguments/tutorial001_py310.py hl[7,12] *}\n\n<div class=\"termy\">\n\n```console\n// Check the help for create\n$ uv run python main.py create --help\n\nUsage: main.py create [OPTIONS] {username}\n\nArguments:\n  username  [required]\n\nOptions:\n  --help  Show this message and exit.\n\n// Call it with a CLI argument\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// The same for delete\n$ uv run python main.py delete Camila\n\nDeleting user: Camila\n```\n\n</div>\n\n/// tip\n\nEverything to the *right* of the *command* are *CLI parameters* (*CLI arguments* and *CLI options*) for that command.\n\n///\n\n/// note | Technical Details\n\nActually, it's everything to the right of that command, *before any subcommand*.\n\nIt's possible to have groups of *subcommands*, it's like if one *command* also had *subcommands*. And then those *subcommands* could have their own *CLI parameters*, taking their own *CLI parameters*.\n\nYou will see about them later in another section.\n\n///\n","docs/tutorial/commands/options.md":"# Command CLI Options\n\nCommands can also have their own *CLI options*.\n\nIn fact, each command can have different *CLI arguments* and *CLI options*:\n\n{* docs_src/commands/options/tutorial001_an_py310.py hl[9,15:18,28:30,39] *}\n\nHere we have multiple commands, with different *CLI parameters*:\n\n* `create`:\n    * `username`: a *CLI argument*.\n* `delete`:\n    * `username`: a *CLI argument*.\n    * `--force`: a *CLI option*, if not provided, it's prompted.\n* `delete-all`:\n    * `--force`: a *CLI option*, if not provided, it's prompted.\n* `init`:\n    * Doesn't take any *CLI parameters*.\n\n<div class=\"termy\">\n\n```console\n// Check the help\npython main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n  delete-all\n  init\n```\n\n</div>\n\n/// tip\n\nCheck the command `delete-all`, by default command names are generated from the function name, replacing `_` with `-`.\n\n///\n\nTest it:\n\n<div class=\"termy\">\n\n```console\n// Check the command create\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// Now test the command delete\n$ uv run python main.py delete Camila\n\n# Are you sure you want to delete the user? [y/n]: $ y\n\nDeleting user: Camila\n\n$ uv run python main.py delete Wade\n\n# Are you sure you want to delete the user? [y/n]: $ n\n\nOperation cancelled\n\n// And finally, the command delete-all\n// Notice it doesn't have CLI arguments, only a CLI option\n\n$ uv run python main.py delete-all\n\n# Are you sure you want to delete ALL users? [y/n]: $ y\n\nDeleting all users\n\n$ uv run python main.py delete-all\n\n# Are you sure you want to delete ALL users? [y/n]: $ n\n\nOperation cancelled\n\n// And if you pass the --force CLI option, it doesn't need to confirm\n\n$ uv run python main.py delete-all --force\n\nDeleting all users\n\n// And init that doesn't take any CLI parameter\n$ uv run python main.py init\n\nInitializing user database\n```\n\n</div>\n","docs/tutorial/commands/name.md":"# Custom Command Name\n\nBy default, the command names are generated from the function name.\n\nSo, if your function is something like:\n\n```Python\ndef create(username: str): ...\n```\n\nThen the command name will be `create`.\n\nBut if you already had a function called `create()` somewhere in your code, you would have to name your CLI function differently.\n\nAnd what if you wanted the command to still be named `create`?\n\nFor this, you can set the name of the command in the first parameter for the `@app.command()` decorator:\n\n{* docs_src/commands/name/tutorial001_py310.py hl[6,11] *}\n\nNow, even though the functions are named `cli_create_user()` and `cli_delete_user()`, the commands will still be named `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test it\n$ uv run python main.py create Camila\n\nCreating user: Camila\n```\n\n</div>\n\nNote that any underscores in the function name will be replaced with dashes.\n\nSo if your function is something like:\n\n```Python\ndef create_user(username: str): ...\n```\nThen the command name will be `create-user`.\n","docs/tutorial/commands/context.md":"# Using the Context\n\nWhen you create a **Typer** application it always has a special, hidden object underneath called the \"Context\".\n\nBut you can access the context by declaring a function parameter of type `typer.Context`.\n\nYou might have read it in [CLI Option Callback and Context](../options/callback-and-context.md).\n\nThe same way, in commands or in the main `Typer` callback you can access the context by declaring a function parameter of type `typer.Context`.\n\n## Getting the context\n\nFor example, let's say that you want to execute some logic in a `Typer` callback depending on the subcommand that is being called.\n\nYou can get the name of the subcommand from the context:\n\n{* docs_src/commands/context/tutorial001_py310.py hl[17,21] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\n// We get the message from the callback\nAbout to execute command: create\nCreating user: Camila\n\n$ uv run python main.py delete Camila\n\n// We get the message from the callback, this time with delete\nAbout to execute command: delete\nDeleting user: Camila\n```\n\n</div>\n\n## Executable callback\n\nBy default, the callback is only executed right before executing a command.\n\nAnd if no command is provided, the help message is shown.\n\nBut we could make it run even without a subcommand with `invoke_without_command=True`:\n\n{* docs_src/commands/context/tutorial002_py310.py hl[16] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py\n\n// The callback is executed, we don't get the default help message\nInitializing database\n\n// Try with a command\n$ uv run python main.py create Camila\n\n// The callback is still executed\nInitializing database\nCreating user: Camila\n```\n\n</div>\n\n## Exclusive executable callback\n\nWe might not want the callback to be executed if there's already other command that will be executed.\n\nFor that, we can get the `typer.Context` and check if there's an invoked command in `ctx.invoked_subcommand`.\n\nIf it's `None`, it means that we are not calling a subcommand but the main program (the callback) directly:\n\n{* docs_src/commands/context/tutorial003_py310.py hl[17,21] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py\n\n// The callback is executed\nInitializing database\n\n// Check it with a subcommand\n$ uv run python main.py create Camila\n\n// This time the callback is not executed\nCreating user: Camila\n```\n\n</div>\n\n## Configuring the context\n\nYou can pass configurations for the context when creating a command or callback.\n\nFor example, you could keep additional *CLI parameters* not declared in your CLI program with `ignore_unknown_options` and `allow_extra_args`.\n\nThen you can access those extra raw *CLI parameters* as a `list` of `str` in `ctx.args`:\n\n{* docs_src/commands/context/tutorial004_py310.py hl[7,9,10] *}\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --name Camila --city Berlin\n\nGot extra arg: --name\nGot extra arg: Camila\nGot extra arg: --city\nGot extra arg: Berlin\n```\n\n</div>\n\n/// tip\n\nNotice that it saves all the extra *CLI parameters* as a raw `list` of `str`, including the *CLI option* names and values, everything together.\n\n///\n","docs/tutorial/commands/callback.md":"# Typer Callback\n\nWhen you create an `app = typer.Typer()` it works as a group of commands.\n\nAnd you can create multiple commands with it.\n\nEach of those commands can have their own *CLI parameters*.\n\nBut as those *CLI parameters* are handled by each of those commands, they don't allow us to create *CLI parameters* for the main CLI application itself.\n\nBut we can use `@app.callback()` for that.\n\nIt's very similar to `@app.command()`, but it declares the *CLI parameters* for the main CLI application (before the commands):\n\n{* docs_src/commands/callback/tutorial001_py310.py hl[25,26,27,28,29,30,31,32] *}\n\nHere we create a `callback` with a `--verbose` *CLI option*.\n\n/// tip\n\nAfter getting the `--verbose` flag, we modify a global `state`, and we use it in the other commands.\n\nThere are other ways to achieve the same, but this will suffice for this example.\n\n///\n\nAnd as we added a docstring to the callback function, by default it will be extracted and used as the help text.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice the main help text, extracted from the callback function: \"Manage users in the awesome CLI app.\"\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Manage users in the awesome CLI app.\n\nOptions:\n  --verbose / --no-verbose  [default: no-verbose]\n  --install-completion      Install completion for the current shell.\n  --show-completion         Show completion for the current shell, to copy it or customize the installation.\n  --help                    Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Check the new top level CLI option --verbose\n\n// Try it normally\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// And now with --verbose\n$ uv run python main.py --verbose create Camila\n\nWill write verbose output\nAbout to create a user\nCreating user: Camila\nJust created a user\n\n// Notice that --verbose belongs to the callback, it has to go before create or delete ⛔️\n$ uv run python main.py create --verbose Camila\n\nUsage: main.py create [OPTIONS] {username}\nTry \"main.py create --help\" for help.\n\nError: No such option: --verbose\n```\n\n</div>\n\n## Adding a callback on creation\n\nIt's also possible to add a callback when creating the `typer.Typer()` app:\n\n{* docs_src/commands/callback/tutorial002_py310.py hl[4,5,8] *}\n\nThat achieves the same as with `@app.callback()`.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\nRunning a command\nCreating user: Camila\n```\n\n</div>\n\n## Overriding a callback\n\nIf you added a callback when creating the `typer.Typer()` app, it's possible to override it with `@app.callback()`:\n\n{* docs_src/commands/callback/tutorial003_py310.py hl[11,12,13] *}\n\nNow `new_callback()` will be the one used.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\n// Notice that the message is the one from new_callback()\nOverride callback, running a command\nCreating user: Camila\n```\n\n</div>\n\n## Adding a callback only for documentation\n\nYou can also add a callback just to add the documentation in the docstring.\n\nIt can be convenient especially if you have several lines of text, as the indentation will be automatically handled for you:\n\n{* docs_src/commands/callback/tutorial004_py310.py hl[8,9,10,11,12,13,14,15,16] *}\n\nNow the callback will be used mainly to extract the docstring for the help text.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n// Notice all the help text extracted from the callback docstring\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Manage users CLI app.\n\n  Use it with the create command.\n\n  A new user with the given 'name' will be created.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// And it just works as normally\n$ uv run python main.py create Camila\n\nCreating user: Camila\n```\n\n</div>\n","docs/tutorial/commands/one-or-multiple.md":"# One or Multiple Commands\n\nYou might have noticed that if you create a single command, as in the following example:\n\n{* docs_src/typer_app/tutorial001_py310.py hl[3,6,12] *}\n\n**Typer** is smart enough to create a CLI application with that single function as the main CLI application, not as a command/subcommand:\n\n<div class=\"termy\">\n\n```console\n// Without a CLI argument\n$ uv run python main.py\n\nUsage: main.py [OPTIONS] {name}\nTry \"main.py --help\" for help.\n\nError: Missing argument 'name'.\n\n// With the 'name' CLI argument\n$ uv run python main.py Camila\n\nHello Camila\n\n// Asking for help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] {name}\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n```\n\n</div>\n\n/// tip\n\nNotice that it doesn't show a command `main`, even though the function name is `main`.\n\n///\n\nBut if you add multiple commands, **Typer** will create one *CLI command* for each one of them:\n\n{* docs_src/commands/index/tutorial002_py310.py hl[6,11] *}\n\nHere we have 2 commands `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test the commands\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n\n$ uv run python main.py delete\n\nDeleting user: Hiro Hamada\n```\n\n</div>\n\n## One command and one callback\n\nIf you want to create a CLI app with one single command but you still want it to be a command/subcommand you can just add a callback:\n\n{* docs_src/commands/one_or_multiple/tutorial001_py310.py hl[11,12,13] *}\n\nAnd now your CLI program will have a single command.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice the single command create\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// Try it\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n```\n\n</div>\n\n## Using the callback to document\n\nNow that you are using a callback just to have a single command, you might as well use it to add documentation for your app:\n\n{* docs_src/commands/one_or_multiple/tutorial002_py310.py hl[11,12,13,14,15,16,17] *}\n\nAnd now the docstring from the callback will be used as the help text:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n// Notice the help text from the docstring\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Creates a single user Hiro Hamada.\n\n  In the next version it will create 5 more users.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// And it still works the same, the callback does nothing\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n```\n\n</div>\n","typer/.agents/skills/typer/SKILL.md":"---\nname: typer\ndescription: Typer best practices and conventions. Use when working with Typer CLIs. Keeps Typer code clean and up to date with the latest features and patterns, updated with new versions. Write new code or refactor and update old code.\n---\n\n# Typer\n\nOfficial Typer skill to write code with best practices, keeping up to date with new versions and features.\n\n## Installing typer\n\nIn a virtual environment, `pip install typer` (with pip) or `uv pip install typer` (with uv). For your library/project, add `typer` to the dependencies in `pyproject.toml`.\n\nDo not install `typer-slim` or `typer-cli`, they are both deprecated and will now simply install `typer`.\n\nTyper supports Python 3.10 and above.\n\n## Use an explicit `Typer` app\n\nFor maximum generalizability, create an explicit Typer app and register subcommand(s), instead of using `typer.run`:\n\n```python\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef hello():\n    print(f\"Hello World\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\ninstead of:\n\n```python\n# DO NOT DO THIS: Not extensible. Use Typer() instead.\nimport typer\n\n\ndef main():\n    print(f\"Hello World\")\n\n\nif __name__ == \"__main__\":\n    typer.run(main)\n```\n\n## Execute the app\n\nTo execute the app in the terminal, run\n\n```bash\npython main.py\n```\n\nWhen multiple commands are registered to the Typer app, you have to add the command name:\n\n```bash\npython main.py hello\n```\n\nTo see the automatically generated help documentation, run\n\n```bash\npython main.py --help\n```\n\nor set `no_args_is_help` to `True` when creating the `Typer()` add to automatically show the help when running a command without any arguments.\n\n## Use `Annotated`\n\nAlways prefer the `Annotated` style for declarations of CLI arguments and options.\n\nIt allows us to pass additional metadata that can be used by Typer.\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef hello(name: Annotated[str, typer.Argument()] = \"World\"):\n    # Note that name is an optional Argument, as a default is provided\n    print(f\"Hello {name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nThis program can be run as-is, or can provide a specific name:\n\n```bash\npython main.py\npython main.py Rick\n```\n\nAn older way of setting a default value is this:\n```python\n# DO NOT DO THIS: old style. Use Annotated instead.\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=\"World\")):\n    # Note that name is an optional Argument, as a default is provided\n    print(f\"Hello {name}\")\n```\n\nSimilarly, the old style could use ellipsis (...) to explicitly mark an argument as required.\n\n```python\n# DO NOT DO THIS: old style. Use Annotated without a default value instead.\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=...)):\n    # Note that name is now a required Argument\n    print(f\"Hello {name}\")\n```\n\n## CLI Options\n\nCLI options are declared in a similar fashion as arguments, but will be called on the CLI with a single dash (single letter) or 2 dashes (full name).\n\nThe CLI option name is automatically generated from the variable name, so `user_name` becomes `--user-name` automatically:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user_name: Annotated[str, typer.Option()]):\n    # On the CLI, the required user name can be specified with --user-name\n    print(f\"Hello {user_name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nIf you want to specify a different name, or want to add a short version, declare them in the `typer.Option`:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user_name: Annotated[str, typer.Option(\"--name\", \"-n\")]):\n    # On the CLI, the required user name can be specified with -n or --name\n    print(f\"Hello {user_name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nYou can run this program as such:\n\n```bash\npython main.py -n \"Rick\"\npython main.py --name \"Morty\"\n```\n\n### CLI options with multiple values\n\nBy declaring a CLI option as a list, it can receive multiple values:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user: Annotated[list[str] | None, typer.Option()] = None):\n    if not user:\n        print(f\"No users provided!\")\n        raise typer.Abort()\n    for u in user:\n        print(f\"Processing user: {u}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nThis can be executed like so:\n\n```bash\npython main.py --user Rick --user Morty --user Summer\n```\n\n## Rich\n\nBy default, Rich can be used with its custom markup syntax to set colors and styles, e.g.\n\n```python\nfrom rich import print\n\nprint(\"[bold red]Alert![/bold red] [green]Portal gun[/green] shooting! :boom:\")\n```\n\nTyper supports using Rich formatting in the docstrings and the help messages of CLI arguments and CLI options.\n\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be [green]created[/green]\")\n    ],\n):\n    \"\"\"\n    [bold green]Create[/bold green] a new [italic]shiny[/italic] user. :sparkles:\n\n    This requires a [underline]username[/underline].\n    \"\"\"\n    print(f\"Creating user: {username}\")\n\n\n@app.command(help=\"[bold red]Delete[/bold red] a user with [italic]username[/italic].\")\ndef delete(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be [red]deleted[/red]\")\n    ],\n):\n    \"\"\"\n    Some internal utility function to delete.\n    \"\"\"\n    print(f\"Deleting user: {username}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nTo disable Rich formatting, set `rich_markup_mode` to `None` when creating a `Typer()` app. By default (when no value is given), Rich formatting is enabled.\n\n### Rich markdown\n\nYou can also set `rich_markup_mode` to `\"markdown\"` to use Markdown in the docstring:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"markdown\")\n\n\n@app.command(help=\"**Delete** a user with *username*.\")\ndef delete(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be **deleted** :boom:\")\n    ],\n):\n    print(f\"Deleting user: {username}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\n## Click\n\nOriginally, Typer was built on Click. However, since version 0.26.0, Typer has vendored Click. As such, Click extensions should not be used anymore.\n\nOther settings of `Option` and `Argument` that came from Click but shouldn't be used in Typer anymore, include: `expose_value`, `shell_complete`, `show_choices`, `errors`, `prompt_required`, `is_flag`, `flag_value` and `allow_from_autoenv`.\n\nCode bases using these should be refactored to use pure Typer functionality.\n","docs/tutorial/commands/index.md":"# Commands\n\nWe have seen how to create a CLI program with possibly several *CLI options* and *CLI arguments*.\n\nBut **Typer** allows you to create CLI programs with several commands (also known as subcommands).\n\nFor example, the program `git` has several commands.\n\nOne command of `git` is `git push`. And `git push` in turn takes its own *CLI arguments* and *CLI options*.\n\nFor example:\n\n<div class=\"termy\">\n\n```console\n// The push command with no parameters\n$ git push\n\n---> 100%\n\n// The push command with one CLI option --set-upstream and 2 CLI arguments\n$ git push --set-upstream origin master\n\n---> 100%\n```\n\n</div>\n\nAnother command of `git` is `git pull`, it also has some *CLI parameters*.\n\nIt's like if the same big program `git` had several small programs inside.\n\n/// tip\n\nA command looks the same as a *CLI argument*, it's just some name without a preceding `--`. But commands have a predefined name, and are used to group different sets of functionalities into the same CLI application.\n\n///\n\n## Command or subcommand\n\nIt's common to call a CLI program a \"command\".\n\nBut when one of these programs have subcommands, those subcommands are also frequently called just \"commands\".\n\nHave that in mind so you don't get confused.\n\nHere I'll use **CLI application** or **program** to refer to the program you are building in Python with Typer, and **command** to refer to one of these \"subcommands\" of your program.\n\n## A CLI application with multiple commands\n\n**Typer** allows creating CLI applications with multiple commands/subcommands.\n\nNow that you know how to create an explicit `typer.Typer()` application and add one command, let's see how to add multiple commands.\n\nLet's say that we have a CLI application to manage users.\n\nWe'll have a command to `create` users and another command to `delete` them.\n\nTo begin, let's say it can only create and delete one single predefined user:\n\n{* docs_src/commands/index/tutorial002_py310.py hl[6,11] *}\n\nNow we have a CLI application with 2 commands, `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test them\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n\n$ uv run python main.py delete\n\nDeleting user: Hiro Hamada\n\n// Now we have 2 commands! 🎉\n```\n\n</div>\n\nNotice that the help text now shows the 2 commands: `create` and `delete`.\n\n/// tip\n\nBy default, the names of the commands are generated from the function name.\n\n///\n\n## Show the help message if no command is given\n\nBy default, we need to specify `--help` to get the command's help page.\n\nHowever, by setting `no_args_is_help=True` when defining the `typer.Typer()` application, the help function will be shown whenever no argument is given:\n\n{* docs_src/commands/index/tutorial003_py310.py hl[3] *}\n\nNow we can run this:\n\n<div class=\"termy\">\n\n```console\n// Check the help without having to type --help\n$ uv run python main.py\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n```\n\n</div>\n\n\n## Sorting of the commands\n\nNote that by design, **Typer** shows the commands in the order they've been declared.\n\nSo, if we take our original example, with `create` and `delete` commands, and reverse the order in the Python file:\n\n{* docs_src/commands/index/tutorial004_py310.py hl[7,12] *}\n\nThen we will see the `delete` command first in the help output:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  delete\n  create\n```\n\n</div>\n\n## Decorator Technical Details\n\nWhen you use `@app.command()` the function under the decorator is registered in the **Typer** application and is then used later by the application.\n\nBut Typer doesn't modify that function itself, the function is left as is.\n\nThat means that if your function is simple enough that you could create it without using `typer.Option()` or `typer.Argument()`, you could use the same function for a **Typer** application and a **FastAPI** application putting both decorators on top, or similar tricks.\n","docs/tutorial/commands/help.md":"# Command Help\n\nThe same as before, you can add help for the commands in the docstrings and the *CLI options*.\n\nAnd the `typer.Typer()` application receives a parameter `help` that you can pass with the main help text for your CLI program:\n\n{* docs_src/commands/help/tutorial001_an_py310.py hl[5,10:12,23,27:31,44,48:52,61:63] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the new help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Awesome CLI user manager.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create      Create a new user with username.\n  delete      Delete a user with username.\n  delete-all  Delete ALL users in the database.\n  init        Initialize the users database.\n\n// Now the commands have inline help 🎉\n\n// Check the help for create\n$ uv run python main.py create --help\n\nUsage: main.py create [OPTIONS] {username}\n\n  Create a new user with username.\n\nArguments:\n  username  [required]\n\nOptions:\n  --help  Show this message and exit.\n\n// Check the help for delete\n$ uv run python main.py delete --help\n\nUsage: main.py delete [OPTIONS] {username}\n\n  Delete a user with username.\n\n  If --force is not used, will ask for confirmation.\n\nArguments:\n  username  [required]\n\nOptions:\n  --force / --no-force  Force deletion without confirmation.  [required]\n  --help                Show this message and exit.\n\n// Check the help for delete-all\n$ uv run python main.py delete-all --help\n\nUsage: main.py delete-all [OPTIONS]\n\n  Delete ALL users in the database.\n\n  If --force is not used, will ask for confirmation.\n\nOptions:\n  --force / --no-force  Force deletion without confirmation.  [required]\n  --help                Show this message and exit.\n\n// Check the help for init\n$ uv run python main.py init --help\n\nUsage: main.py init [OPTIONS]\n\n  Initialize the users database.\n\nOptions:\n  --help  Show this message and exit.\n```\n\n</div>\n\n/// tip\n\n`typer.Typer()` receives several other parameters for other things, we'll see that later.\n\nYou will also see how to use \"Callbacks\" later, and those include a way to add this same help message in a function docstring.\n\n///\n\n## Overwrite command help\n\nYou will probably be better adding the help text as a docstring to your functions, but if for some reason you wanted to overwrite it, you can use the `help` function argument passed to `@app.command()`:\n\n{* docs_src/commands/help/tutorial002_py310.py hl[6,14] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice it uses the help passed to @app.command()\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy\n                        it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create  Create a new user with username.\n  delete  Delete a user with username.\n\n// It uses \"Create a new user with username.\" instead of \"Some internal utility function to create.\"\n```\n\n</div>\n\n## Deprecate a Command\n\nThere could be cases where you have a command in your app that you need to deprecate, so that your users stop using it, even while it's still supported for a while.\n\nYou can mark it with the parameter `deprecated=True`:\n\n{* docs_src/commands/help/tutorial003_py310.py hl[14] *}\n\nAnd when you show the `--help` option you will see it's marked as \"`deprecated`\":\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                  </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create       </b></font> Create a user.                                      │\n<font color=\"#A5A5A1\">│ </font><font color=\"#6B9F98\"><b>delete       </b></font> Delete a user.              <font color=\"#F92672\">(deprecated)           </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd if you check the `--help` for the deprecated command (in this example, the command `delete`), it also shows it as deprecated:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                  </b>\n<b>                                                                     </b>\n <font color=\"#F92672\">(deprecated) </font>\n Delete a user.\n This is deprecated and will stop being supported soon.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  <font color=\"#A6194C\">[required]</font>                              │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n## Suggest Commands\n\nAs of version 0.20.0, Typer added support for suggesting mistyped command names. This feature is **enabled by default**, but you can disable it with the parameter `suggest_commands=False`:\n\n{* docs_src/commands/index/tutorial005_py310.py hl[3] *}\n\nIf a user mistypes a command, they'll see a helpful suggestion:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py crate\n\n<font color=\"#C4A000\">Usage: </font>main.py [OPTIONS] COMMAND [ARGS]...\n<font color=\"#AAAAAA\">Try </font><font color=\"#22436D\">&apos;main.py </font><font color=\"#4C6A8A\"><b>--help</b></font><font color=\"#22436D\">&apos;</font><font color=\"#AAAAAA\"> for help.</font>\n<font color=\"#CC0000\">╭─ Error ───────────────────────────────────────────────────────────╮</font>\n<font color=\"#CC0000\">│</font> No such command &apos;crate&apos;. Did you mean &apos;create&apos;?                   <font color=\"#CC0000\">│</font>\n<font color=\"#CC0000\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nIf there are multiple close matches, Typer will suggest them all. This feature uses Python's built-in `difflib.get_close_matches()` to find similar command names, making your CLI more user-friendly by helping users recover from typos.\n\n## Rich Markdown and Markup\n\nTyper installs **Rich** to allow for more formatting in the docstrings and the `help` parameter for *CLI arguments* and *CLI options*. You will see more about it below. 👇\n\n/// note\n\nYou can disable rich text formatting by setting `rich_markup_mode` to `None` for your specific app.\nAlternatively, you can disable it globally using an environmental variable `TYPER_USE_RICH` set to `False` or `0`.\n\n///\n\n### Rich Markup\n\nIf you set `rich_markup_mode=\"rich\"` when creating the `typer.Typer()` app (which is the default), you will be able to use [Rich Console Markup](https://rich.readthedocs.io/en/stable/markup.html) in the docstring, and even in the help for the *CLI arguments* and options:\n\n{* docs_src/commands/help/tutorial004_an_py310.py hl[5,11,15:17,22,25,28] *}\n\nWith that, you can use [Rich Console Markup](https://rich.readthedocs.io/en/stable/markup.html) to format the text in the docstring for the command `create`, make the word \"`create`\" bold and green, and even use an [emoji](https://rich.readthedocs.io/en/stable/markup.html#emoji).\n\nYou can also use markup in the help for the `username` CLI Argument.\n\nAnd the same as before, the help text overwritten for the command `delete` can also use Rich Markup, the same in the CLI Argument and CLI Option.\n\nIf you run the program and check the help, you will see that **Typer** uses **Rich** internally to format the help.\n\nCheck the help for the `create` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username}                   </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\"><b>Create</b></font> a new <i>shiny</i> user. ✨\n This requires a <font color=\"#A5A5A1\"><u style=\"text-decoration-style:single\">username</u></font><font color=\"#A5A5A1\">.                                           </font>\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <font color=\"#A6E22E\">created</font>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                </font>               │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd check the help for the `delete` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <font color=\"#F92672\"><b>Delete</b></font> a user with <i>username</i>.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <font color=\"#F92672\">deleted</font>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                </font>               │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the <font color=\"#F92672\"><b>deletion</b></font> 💥                  │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n### Rich Markdown\n\nIf you set `rich_markup_mode=\"markdown\"` when creating the `typer.Typer()` app, you will be able to use Markdown in the docstring:\n\n{* docs_src/commands/help/tutorial005_an_py310.py hl[5,10,13:21,26,28:29] *}\n\nWith that, you can use Markdown to format the text in the docstring for the command `create`, make the word \"`create`\" bold, show a list of items, and even use an [emoji](https://rich.readthedocs.io/en/stable/markup.html#emoji).\n\nAnd the same as before, the help text overwritten for the command `delete` can also use Markdown.\n\nCheck the help for the `create` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <b>Create</b> a new <i>shiny</i> user. ✨\n\n <font color=\"#F4BF75\"><b> • </b></font><font color=\"#A5A5A1\">Create a username                                                </font>\n <font color=\"#F4BF75\"><b> • </b></font><font color=\"#A5A5A1\">Show that the username is created                                </font>\n\n <font color=\"#F4BF75\">───────────────────────────────────────────────────────────────────</font>\n Learn more at the <font color=\"#44919F\">Typer docs website</font>\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <b>created</b>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                              </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd the same for the `delete` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <b>Delete</b> a user with <i>username</i>.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <b>deleted</b>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                              </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the <b>deletion</b> 💥                  │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n/// note\n\nNotice that in Markdown you cannot define colors. For colors you might prefer to use Rich markup.\n\n///\n\n## Help Panels\n\nIf you have many commands or CLI parameters, you might want to show their documentation in different panels when using the `--help` option.\n\nIf you installed [Rich](https://rich.readthedocs.io/) as described in [Printing and Colors](../printing.md), you can configure the panel to use for each command or CLI parameter.\n\n### Help Panels for Commands\n\nTo set the panel for a command you can pass the argument `rich_help_panel` with the name of the panel you want to use:\n\n{* docs_src/commands/help/tutorial006_py310.py hl[22,30,38,46] *}\n\nCommands without a panel will be shown in the default panel `Commands`, and the rest will be shown in the next panels:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                   </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create          </b></font> <font color=\"#A6E22E\">Create</font> a new user. ✨                            │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>delete          </b></font> <font color=\"#F92672\">Delete</font> a user. ❌                                │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Utils and Configs ───────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>config  </b></font> <font color=\"#66D9EF\">Configure</font> the system. ⚙                                 │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>sync    </b></font> <font color=\"#66D9EF\">Synchronize</font> the system or something fancy like that. ♻  │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Help and Others ─────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>help         </b></font> Get <font color=\"#F4BF75\">help</font> with the system. ❓                        │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>report       </b></font> <font color=\"#F4BF75\">Report</font> an issue. ❗                                 │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n### Help Panels for CLI Parameters\n\nThe same way, you can configure the panels for *CLI arguments* and *CLI options* with `rich_help_panel`.\n\nAnd of course, in the same application you can also set the `rich_help_panel` for commands.\n\n{* docs_src/commands/help/tutorial007_an_py310.py hl[14,20,26,36] *}\n\nThen if you run the application you will see all the *CLI parameters* in their respective panels.\n\n* First the ***CLI arguments*** that don't have a panel name set in a **default** one named \"`Arguments`\".\n* Next the ***CLI arguments*** with a **custom panel**. In this example named \"`Secondary Arguments`\".\n* After that, the ***CLI options*** that don't have a panel in a **default** one named \"`Options`\".\n* And finally, the ***CLI options*** with a **custom panel** set. In this example named \"`Additional Data`\".\n\nYou can check the `--help` option for the command `create`:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username} [lastname]          </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\">Create</font> a new user. ✨\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to create                  │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]            </font>                   │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Secondary Arguments ─────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│   lastname      </font><font color=\"#A37F4E\"><b>lastname</b></font>  The last name of the new user           │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the creation of the user         │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Additional Data ─────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--age</b></font>                   <font color=\"#F4BF75\"><b>&lt;int&gt;   </b></font>  The age of the new user         │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--favorite-color</b></font>        <font color=\"#F4BF75\"><b>&lt;str&gt;   </b></font>  The favorite color of the new   │\n<font color=\"#A5A5A1\">│                                  user                             │</font>\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd of course, the `rich_help_panel` can be used in the same way for commands in the same application.\n\nAnd those panels will be shown when you use the main `--help` option.\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                   </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create          </b></font> <font color=\"#A6E22E\">Create</font> a new user. ✨                            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Utils and Configs ───────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>config         </b></font> <font color=\"#66D9EF\">Configure</font> the system. ⚙                          │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nYou can see the custom panel for the commands for \"`Utils and Configs`\".\n\n## Epilog\n\nIf you need, you can also add an epilog section to the help of your commands:\n\n{* docs_src/commands/help/tutorial008_py310.py hl[6] *}\n\nAnd when you check the `--help` option it will look like:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] {username}                            </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\">Create</font> a new user. ✨\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>                  <font color=\"#A6194C\">[required]</font>              │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n\n Made with ❤ in <font color=\"#66D9EF\">Venus</font>\n```\n\n</div>\n"},"items":[{"name":"SKILL.md","path":"typer/.agents/skills/typer/SKILL.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/typer/.agents/skills/typer/SKILL.md","title":"typer","category":"anthropic-skill","format":"markdown","content":"---\nname: typer\ndescription: Typer best practices and conventions. Use when working with Typer CLIs. Keeps Typer code clean and up to date with the latest features and patterns, updated with new versions. Write new code or refactor and update old code.\n---\n\n# Typer\n\nOfficial Typer skill to write code with best practices, keeping up to date with new versions and features.\n\n## Installing typer\n\nIn a virtual environment, `pip install typer` (with pip) or `uv pip install typer` (with uv). For your library/project, add `typer` to the dependencies in `pyproject.toml`.\n\nDo not install `typer-slim` or `typer-cli`, they are both deprecated and will now simply install `typer`.\n\nTyper supports Python 3.10 and above.\n\n## Use an explicit `Typer` app\n\nFor maximum generalizability, create an explicit Typer app and register subcommand(s), instead of using `typer.run`:\n\n```python\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef hello():\n    print(f\"Hello World\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\ninstead of:\n\n```python\n# DO NOT DO THIS: Not extensible. Use Typer() instead.\nimport typer\n\n\ndef main():\n    print(f\"Hello World\")\n\n\nif __name__ == \"__main__\":\n    typer.run(main)\n```\n\n## Execute the app\n\nTo execute the app in the terminal, run\n\n```bash\npython main.py\n```\n\nWhen multiple commands are registered to the Typer app, you have to add the command name:\n\n```bash\npython main.py hello\n```\n\nTo see the automatically generated help documentation, run\n\n```bash\npython main.py --help\n```\n\nor set `no_args_is_help` to `True` when creating the `Typer()` add to automatically show the help when running a command without any arguments.\n\n## Use `Annotated`\n\nAlways prefer the `Annotated` style for declarations of CLI arguments and options.\n\nIt allows us to pass additional metadata that can be used by Typer.\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef hello(name: Annotated[str, typer.Argument()] = \"World\"):\n    # Note that name is an optional Argument, as a default is provided\n    print(f\"Hello {name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nThis program can be run as-is, or can provide a specific name:\n\n```bash\npython main.py\npython main.py Rick\n```\n\nAn older way of setting a default value is this:\n```python\n# DO NOT DO THIS: old style. Use Annotated instead.\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=\"World\")):\n    # Note that name is an optional Argument, as a default is provided\n    print(f\"Hello {name}\")\n```\n\nSimilarly, the old style could use ellipsis (...) to explicitly mark an argument as required.\n\n```python\n# DO NOT DO THIS: old style. Use Annotated without a default value instead.\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=...)):\n    # Note that name is now a required Argument\n    print(f\"Hello {name}\")\n```\n\n## CLI Options\n\nCLI options are declared in a similar fashion as arguments, but will be called on the CLI with a single dash (single letter) or 2 dashes (full name).\n\nThe CLI option name is automatically generated from the variable name, so `user_name` becomes `--user-name` automatically:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user_name: Annotated[str, typer.Option()]):\n    # On the CLI, the required user name can be specified with --user-name\n    print(f\"Hello {user_name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nIf you want to specify a different name, or want to add a short version, declare them in the `typer.Option`:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user_name: Annotated[str, typer.Option(\"--name\", \"-n\")]):\n    # On the CLI, the required user name can be specified with -n or --name\n    print(f\"Hello {user_name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nYou can run this program as such:\n\n```bash\npython main.py -n \"Rick\"\npython main.py --name \"Morty\"\n```\n\n### CLI options with multiple values\n\nBy declaring a CLI option as a list, it can receive multiple values:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user: Annotated[list[str] | None, typer.Option()] = None):\n    if not user:\n        print(f\"No users provided!\")\n        raise typer.Abort()\n    for u in user:\n        print(f\"Processing user: {u}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nThis can be executed like so:\n\n```bash\npython main.py --user Rick --user Morty --user Summer\n```\n\n## Rich\n\nBy default, Rich can be used with its custom markup syntax to set colors and styles, e.g.\n\n```python\nfrom rich import print\n\nprint(\"[bold red]Alert![/bold red] [green]Portal gun[/green] shooting! :boom:\")\n```\n\nTyper supports using Rich formatting in the docstrings and the help messages of CLI arguments and CLI options.\n\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be [green]created[/green]\")\n    ],\n):\n    \"\"\"\n    [bold green]Create[/bold green] a new [italic]shiny[/italic] user. :sparkles:\n\n    This requires a [underline]username[/underline].\n    \"\"\"\n    print(f\"Creating user: {username}\")\n\n\n@app.command(help=\"[bold red]Delete[/bold red] a user with [italic]username[/italic].\")\ndef delete(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be [red]deleted[/red]\")\n    ],\n):\n    \"\"\"\n    Some internal utility function to delete.\n    \"\"\"\n    print(f\"Deleting user: {username}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nTo disable Rich formatting, set `rich_markup_mode` to `None` when creating a `Typer()` app. By default (when no value is given), Rich formatting is enabled.\n\n### Rich markdown\n\nYou can also set `rich_markup_mode` to `\"markdown\"` to use Markdown in the docstring:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"markdown\")\n\n\n@app.command(help=\"**Delete** a user with *username*.\")\ndef delete(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be **deleted** :boom:\")\n    ],\n):\n    print(f\"Deleting user: {username}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\n## Click\n\nOriginally, Typer was built on Click. However, since version 0.26.0, Typer has vendored Click. As such, Click extensions should not be used anymore.\n\nOther settings of `Option` and `Argument` that came from Click but shouldn't be used in Typer anymore, include: `expose_value`, `shell_complete`, `show_choices`, `errors`, `prompt_required`, `is_flag`, `flag_value` and `allow_from_autoenv`.\n\nCode bases using these should be refactored to use pure Typer functionality.\n","frontmatter":{"name":"typer","description":"Typer best practices and conventions. Use when working with Typer CLIs. Keeps Typer code clean and up to date with the latest features and patterns, updated with new versions. Write new code or refactor and update old code."},"isInternal":false,"tokens":1677,"sizeBytes":6728},{"name":"arguments.md","path":"docs/tutorial/commands/arguments.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/docs/tutorial/commands/arguments.md","title":"Command: /arguments","category":"command-prompt","format":"markdown","content":"# Command CLI Arguments\n\nThe same way as with a CLI application with a single command, subcommands (or just \"commands\") can also have their own *CLI arguments*:\n\n{* docs_src/commands/arguments/tutorial001_py310.py hl[7,12] *}\n\n<div class=\"termy\">\n\n```console\n// Check the help for create\n$ uv run python main.py create --help\n\nUsage: main.py create [OPTIONS] {username}\n\nArguments:\n  username  [required]\n\nOptions:\n  --help  Show this message and exit.\n\n// Call it with a CLI argument\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// The same for delete\n$ uv run python main.py delete Camila\n\nDeleting user: Camila\n```\n\n</div>\n\n/// tip\n\nEverything to the *right* of the *command* are *CLI parameters* (*CLI arguments* and *CLI options*) for that command.\n\n///\n\n/// note | Technical Details\n\nActually, it's everything to the right of that command, *before any subcommand*.\n\nIt's possible to have groups of *subcommands*, it's like if one *command* also had *subcommands*. And then those *subcommands* could have their own *CLI parameters*, taking their own *CLI parameters*.\n\nYou will see about them later in another section.\n\n///\n","isInternal":false,"tokens":280,"sizeBytes":1146},{"name":"callback.md","path":"docs/tutorial/commands/callback.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/docs/tutorial/commands/callback.md","title":"Command: /callback","category":"command-prompt","format":"markdown","content":"# Typer Callback\n\nWhen you create an `app = typer.Typer()` it works as a group of commands.\n\nAnd you can create multiple commands with it.\n\nEach of those commands can have their own *CLI parameters*.\n\nBut as those *CLI parameters* are handled by each of those commands, they don't allow us to create *CLI parameters* for the main CLI application itself.\n\nBut we can use `@app.callback()` for that.\n\nIt's very similar to `@app.command()`, but it declares the *CLI parameters* for the main CLI application (before the commands):\n\n{* docs_src/commands/callback/tutorial001_py310.py hl[25,26,27,28,29,30,31,32] *}\n\nHere we create a `callback` with a `--verbose` *CLI option*.\n\n/// tip\n\nAfter getting the `--verbose` flag, we modify a global `state`, and we use it in the other commands.\n\nThere are other ways to achieve the same, but this will suffice for this example.\n\n///\n\nAnd as we added a docstring to the callback function, by default it will be extracted and used as the help text.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice the main help text, extracted from the callback function: \"Manage users in the awesome CLI app.\"\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Manage users in the awesome CLI app.\n\nOptions:\n  --verbose / --no-verbose  [default: no-verbose]\n  --install-completion      Install completion for the current shell.\n  --show-completion         Show completion for the current shell, to copy it or customize the installation.\n  --help                    Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Check the new top level CLI option --verbose\n\n// Try it normally\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// And now with --verbose\n$ uv run python main.py --verbose create Camila\n\nWill write verbose output\nAbout to create a user\nCreating user: Camila\nJust created a user\n\n// Notice that --verbose belongs to the callback, it has to go before create or delete ⛔️\n$ uv run python main.py create --verbose Camila\n\nUsage: main.py create [OPTIONS] {username}\nTry \"main.py create --help\" for help.\n\nError: No such option: --verbose\n```\n\n</div>\n\n## Adding a callback on creation\n\nIt's also possible to add a callback when creating the `typer.Typer()` app:\n\n{* docs_src/commands/callback/tutorial002_py310.py hl[4,5,8] *}\n\nThat achieves the same as with `@app.callback()`.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\nRunning a command\nCreating user: Camila\n```\n\n</div>\n\n## Overriding a callback\n\nIf you added a callback when creating the `typer.Typer()` app, it's possible to override it with `@app.callback()`:\n\n{* docs_src/commands/callback/tutorial003_py310.py hl[11,12,13] *}\n\nNow `new_callback()` will be the one used.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\n// Notice that the message is the one from new_callback()\nOverride callback, running a command\nCreating user: Camila\n```\n\n</div>\n\n## Adding a callback only for documentation\n\nYou can also add a callback just to add the documentation in the docstring.\n\nIt can be convenient especially if you have several lines of text, as the indentation will be automatically handled for you:\n\n{* docs_src/commands/callback/tutorial004_py310.py hl[8,9,10,11,12,13,14,15,16] *}\n\nNow the callback will be used mainly to extract the docstring for the help text.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n// Notice all the help text extracted from the callback docstring\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Manage users CLI app.\n\n  Use it with the create command.\n\n  A new user with the given 'name' will be created.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// And it just works as normally\n$ uv run python main.py create Camila\n\nCreating user: Camila\n```\n\n</div>\n","isInternal":false,"tokens":986,"sizeBytes":4062},{"name":"context.md","path":"docs/tutorial/commands/context.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/docs/tutorial/commands/context.md","title":"Command: /context","category":"command-prompt","format":"markdown","content":"# Using the Context\n\nWhen you create a **Typer** application it always has a special, hidden object underneath called the \"Context\".\n\nBut you can access the context by declaring a function parameter of type `typer.Context`.\n\nYou might have read it in [CLI Option Callback and Context](../options/callback-and-context.md).\n\nThe same way, in commands or in the main `Typer` callback you can access the context by declaring a function parameter of type `typer.Context`.\n\n## Getting the context\n\nFor example, let's say that you want to execute some logic in a `Typer` callback depending on the subcommand that is being called.\n\nYou can get the name of the subcommand from the context:\n\n{* docs_src/commands/context/tutorial001_py310.py hl[17,21] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\n// We get the message from the callback\nAbout to execute command: create\nCreating user: Camila\n\n$ uv run python main.py delete Camila\n\n// We get the message from the callback, this time with delete\nAbout to execute command: delete\nDeleting user: Camila\n```\n\n</div>\n\n## Executable callback\n\nBy default, the callback is only executed right before executing a command.\n\nAnd if no command is provided, the help message is shown.\n\nBut we could make it run even without a subcommand with `invoke_without_command=True`:\n\n{* docs_src/commands/context/tutorial002_py310.py hl[16] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py\n\n// The callback is executed, we don't get the default help message\nInitializing database\n\n// Try with a command\n$ uv run python main.py create Camila\n\n// The callback is still executed\nInitializing database\nCreating user: Camila\n```\n\n</div>\n\n## Exclusive executable callback\n\nWe might not want the callback to be executed if there's already other command that will be executed.\n\nFor that, we can get the `typer.Context` and check if there's an invoked command in `ctx.invoked_subcommand`.\n\nIf it's `None`, it means that we are not calling a subcommand but the main program (the callback) directly:\n\n{* docs_src/commands/context/tutorial003_py310.py hl[17,21] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py\n\n// The callback is executed\nInitializing database\n\n// Check it with a subcommand\n$ uv run python main.py create Camila\n\n// This time the callback is not executed\nCreating user: Camila\n```\n\n</div>\n\n## Configuring the context\n\nYou can pass configurations for the context when creating a command or callback.\n\nFor example, you could keep additional *CLI parameters* not declared in your CLI program with `ignore_unknown_options` and `allow_extra_args`.\n\nThen you can access those extra raw *CLI parameters* as a `list` of `str` in `ctx.args`:\n\n{* docs_src/commands/context/tutorial004_py310.py hl[7,9,10] *}\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --name Camila --city Berlin\n\nGot extra arg: --name\nGot extra arg: Camila\nGot extra arg: --city\nGot extra arg: Berlin\n```\n\n</div>\n\n/// tip\n\nNotice that it saves all the extra *CLI parameters* as a raw `list` of `str`, including the *CLI option* names and values, everything together.\n\n///\n","isInternal":false,"tokens":742,"sizeBytes":3152},{"name":"help.md","path":"docs/tutorial/commands/help.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/docs/tutorial/commands/help.md","title":"Command: /help","category":"command-prompt","format":"markdown","content":"# Command Help\n\nThe same as before, you can add help for the commands in the docstrings and the *CLI options*.\n\nAnd the `typer.Typer()` application receives a parameter `help` that you can pass with the main help text for your CLI program:\n\n{* docs_src/commands/help/tutorial001_an_py310.py hl[5,10:12,23,27:31,44,48:52,61:63] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the new help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Awesome CLI user manager.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create      Create a new user with username.\n  delete      Delete a user with username.\n  delete-all  Delete ALL users in the database.\n  init        Initialize the users database.\n\n// Now the commands have inline help 🎉\n\n// Check the help for create\n$ uv run python main.py create --help\n\nUsage: main.py create [OPTIONS] {username}\n\n  Create a new user with username.\n\nArguments:\n  username  [required]\n\nOptions:\n  --help  Show this message and exit.\n\n// Check the help for delete\n$ uv run python main.py delete --help\n\nUsage: main.py delete [OPTIONS] {username}\n\n  Delete a user with username.\n\n  If --force is not used, will ask for confirmation.\n\nArguments:\n  username  [required]\n\nOptions:\n  --force / --no-force  Force deletion without confirmation.  [required]\n  --help                Show this message and exit.\n\n// Check the help for delete-all\n$ uv run python main.py delete-all --help\n\nUsage: main.py delete-all [OPTIONS]\n\n  Delete ALL users in the database.\n\n  If --force is not used, will ask for confirmation.\n\nOptions:\n  --force / --no-force  Force deletion without confirmation.  [required]\n  --help                Show this message and exit.\n\n// Check the help for init\n$ uv run python main.py init --help\n\nUsage: main.py init [OPTIONS]\n\n  Initialize the users database.\n\nOptions:\n  --help  Show this message and exit.\n```\n\n</div>\n\n/// tip\n\n`typer.Typer()` receives several other parameters for other things, we'll see that later.\n\nYou will also see how to use \"Callbacks\" later, and those include a way to add this same help message in a function docstring.\n\n///\n\n## Overwrite command help\n\nYou will probably be better adding the help text as a docstring to your functions, but if for some reason you wanted to overwrite it, you can use the `help` function argument passed to `@app.command()`:\n\n{* docs_src/commands/help/tutorial002_py310.py hl[6,14] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice it uses the help passed to @app.command()\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy\n                        it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create  Create a new user with username.\n  delete  Delete a user with username.\n\n// It uses \"Create a new user with username.\" instead of \"Some internal utility function to create.\"\n```\n\n</div>\n\n## Deprecate a Command\n\nThere could be cases where you have a command in your app that you need to deprecate, so that your users stop using it, even while it's still supported for a while.\n\nYou can mark it with the parameter `deprecated=True`:\n\n{* docs_src/commands/help/tutorial003_py310.py hl[14] *}\n\nAnd when you show the `--help` option you will see it's marked as \"`deprecated`\":\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                  </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create       </b></font> Create a user.                                      │\n<font color=\"#A5A5A1\">│ </font><font color=\"#6B9F98\"><b>delete       </b></font> Delete a user.              <font color=\"#F92672\">(deprecated)           </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd if you check the `--help` for the deprecated command (in this example, the command `delete`), it also shows it as deprecated:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                  </b>\n<b>                                                                     </b>\n <font color=\"#F92672\">(deprecated) </font>\n Delete a user.\n This is deprecated and will stop being supported soon.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  <font color=\"#A6194C\">[required]</font>                              │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n## Suggest Commands\n\nAs of version 0.20.0, Typer added support for suggesting mistyped command names. This feature is **enabled by default**, but you can disable it with the parameter `suggest_commands=False`:\n\n{* docs_src/commands/index/tutorial005_py310.py hl[3] *}\n\nIf a user mistypes a command, they'll see a helpful suggestion:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py crate\n\n<font color=\"#C4A000\">Usage: </font>main.py [OPTIONS] COMMAND [ARGS]...\n<font color=\"#AAAAAA\">Try </font><font color=\"#22436D\">&apos;main.py </font><font color=\"#4C6A8A\"><b>--help</b></font><font color=\"#22436D\">&apos;</font><font color=\"#AAAAAA\"> for help.</font>\n<font color=\"#CC0000\">╭─ Error ───────────────────────────────────────────────────────────╮</font>\n<font color=\"#CC0000\">│</font> No such command &apos;crate&apos;. Did you mean &apos;create&apos;?                   <font color=\"#CC0000\">│</font>\n<font color=\"#CC0000\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nIf there are multiple close matches, Typer will suggest them all. This feature uses Python's built-in `difflib.get_close_matches()` to find similar command names, making your CLI more user-friendly by helping users recover from typos.\n\n## Rich Markdown and Markup\n\nTyper installs **Rich** to allow for more formatting in the docstrings and the `help` parameter for *CLI arguments* and *CLI options*. You will see more about it below. 👇\n\n/// note\n\nYou can disable rich text formatting by setting `rich_markup_mode` to `None` for your specific app.\nAlternatively, you can disable it globally using an environmental variable `TYPER_USE_RICH` set to `False` or `0`.\n\n///\n\n### Rich Markup\n\nIf you set `rich_markup_mode=\"rich\"` when creating the `typer.Typer()` app (which is the default), you will be able to use [Rich Console Markup](https://rich.readthedocs.io/en/stable/markup.html) in the docstring, and even in the help for the *CLI arguments* and options:\n\n{* docs_src/commands/help/tutorial004_an_py310.py hl[5,11,15:17,22,25,28] *}\n\nWith that, you can use [Rich Console Markup](https://rich.readthedocs.io/en/stable/markup.html) to format the text in the docstring for the command `create`, make the word \"`create`\" bold and green, and even use an [emoji](https://rich.readthedocs.io/en/stable/markup.html#emoji).\n\nYou can also use markup in the help for the `username` CLI Argument.\n\nAnd the same as before, the help text overwritten for the command `delete` can also use Rich Markup, the same in the CLI Argument and CLI Option.\n\nIf you run the program and check the help, you will see that **Typer** uses **Rich** internally to format the help.\n\nCheck the help for the `create` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username}                   </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\"><b>Create</b></font> a new <i>shiny</i> user. ✨\n This requires a <font color=\"#A5A5A1\"><u style=\"text-decoration-style:single\">username</u></font><font color=\"#A5A5A1\">.                                           </font>\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <font color=\"#A6E22E\">created</font>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                </font>               │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd check the help for the `delete` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <font color=\"#F92672\"><b>Delete</b></font> a user with <i>username</i>.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <font color=\"#F92672\">deleted</font>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                </font>               │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the <font color=\"#F92672\"><b>deletion</b></font> 💥                  │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n### Rich Markdown\n\nIf you set `rich_markup_mode=\"markdown\"` when creating the `typer.Typer()` app, you will be able to use Markdown in the docstring:\n\n{* docs_src/commands/help/tutorial005_an_py310.py hl[5,10,13:21,26,28:29] *}\n\nWith that, you can use Markdown to format the text in the docstring for the command `create`, make the word \"`create`\" bold, show a list of items, and even use an [emoji](https://rich.readthedocs.io/en/stable/markup.html#emoji).\n\nAnd the same as before, the help text overwritten for the command `delete` can also use Markdown.\n\nCheck the help for the `create` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <b>Create</b> a new <i>shiny</i> user. ✨\n\n <font color=\"#F4BF75\"><b> • </b></font><font color=\"#A5A5A1\">Create a username                                                </font>\n <font color=\"#F4BF75\"><b> • </b></font><font color=\"#A5A5A1\">Show that the username is created                                </font>\n\n <font color=\"#F4BF75\">───────────────────────────────────────────────────────────────────</font>\n Learn more at the <font color=\"#44919F\">Typer docs website</font>\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <b>created</b>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                              </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd the same for the `delete` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <b>Delete</b> a user with <i>username</i>.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <b>deleted</b>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                              </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the <b>deletion</b> 💥                  │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n/// note\n\nNotice that in Markdown you cannot define colors. For colors you might prefer to use Rich markup.\n\n///\n\n## Help Panels\n\nIf you have many commands or CLI parameters, you might want to show their documentation in different panels when using the `--help` option.\n\nIf you installed [Rich](https://rich.readthedocs.io/) as described in [Printing and Colors](../printing.md), you can configure the panel to use for each command or CLI parameter.\n\n### Help Panels for Commands\n\nTo set the panel for a command you can pass the argument `rich_help_panel` with the name of the panel you want to use:\n\n{* docs_src/commands/help/tutorial006_py310.py hl[22,30,38,46] *}\n\nCommands without a panel will be shown in the default panel `Commands`, and the rest will be shown in the next panels:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                   </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create          </b></font> <font color=\"#A6E22E\">Create</font> a new user. ✨                            │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>delete          </b></font> <font color=\"#F92672\">Delete</font> a user. ❌                                │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Utils and Configs ───────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>config  </b></font> <font color=\"#66D9EF\">Configure</font> the system. ⚙                                 │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>sync    </b></font> <font color=\"#66D9EF\">Synchronize</font> the system or something fancy like that. ♻  │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Help and Others ─────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>help         </b></font> Get <font color=\"#F4BF75\">help</font> with the system. ❓                        │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>report       </b></font> <font color=\"#F4BF75\">Report</font> an issue. ❗                                 │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n### Help Panels for CLI Parameters\n\nThe same way, you can configure the panels for *CLI arguments* and *CLI options* with `rich_help_panel`.\n\nAnd of course, in the same application you can also set the `rich_help_panel` for commands.\n\n{* docs_src/commands/help/tutorial007_an_py310.py hl[14,20,26,36] *}\n\nThen if you run the application you will see all the *CLI parameters* in their respective panels.\n\n* First the ***CLI arguments*** that don't have a panel name set in a **default** one named \"`Arguments`\".\n* Next the ***CLI arguments*** with a **custom panel**. In this example named \"`Secondary Arguments`\".\n* After that, the ***CLI options*** that don't have a panel in a **default** one named \"`Options`\".\n* And finally, the ***CLI options*** with a **custom panel** set. In this example named \"`Additional Data`\".\n\nYou can check the `--help` option for the command `create`:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username} [lastname]          </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\">Create</font> a new user. ✨\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to create                  │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]            </font>                   │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Secondary Arguments ─────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│   lastname      </font><font color=\"#A37F4E\"><b>lastname</b></font>  The last name of the new user           │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the creation of the user         │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Additional Data ─────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--age</b></font>                   <font color=\"#F4BF75\"><b>&lt;int&gt;   </b></font>  The age of the new user         │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--favorite-color</b></font>        <font color=\"#F4BF75\"><b>&lt;str&gt;   </b></font>  The favorite color of the new   │\n<font color=\"#A5A5A1\">│                                  user                             │</font>\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd of course, the `rich_help_panel` can be used in the same way for commands in the same application.\n\nAnd those panels will be shown when you use the main `--help` option.\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                   </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create          </b></font> <font color=\"#A6E22E\">Create</font> a new user. ✨                            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Utils and Configs ───────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>config         </b></font> <font color=\"#66D9EF\">Configure</font> the system. ⚙                          │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nYou can see the custom panel for the commands for \"`Utils and Configs`\".\n\n## Epilog\n\nIf you need, you can also add an epilog section to the help of your commands:\n\n{* docs_src/commands/help/tutorial008_py310.py hl[6] *}\n\nAnd when you check the `--help` option it will look like:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] {username}                            </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\">Create</font> a new user. ✨\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>                  <font color=\"#A6194C\">[required]</font>              │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n\n Made with ❤ in <font color=\"#66D9EF\">Venus</font>\n```\n\n</div>\n","isInternal":false,"tokens":7372,"sizeBytes":33733},{"name":"index.md","path":"docs/tutorial/commands/index.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/docs/tutorial/commands/index.md","title":"Command: /index","category":"command-prompt","format":"markdown","content":"# Commands\n\nWe have seen how to create a CLI program with possibly several *CLI options* and *CLI arguments*.\n\nBut **Typer** allows you to create CLI programs with several commands (also known as subcommands).\n\nFor example, the program `git` has several commands.\n\nOne command of `git` is `git push`. And `git push` in turn takes its own *CLI arguments* and *CLI options*.\n\nFor example:\n\n<div class=\"termy\">\n\n```console\n// The push command with no parameters\n$ git push\n\n---> 100%\n\n// The push command with one CLI option --set-upstream and 2 CLI arguments\n$ git push --set-upstream origin master\n\n---> 100%\n```\n\n</div>\n\nAnother command of `git` is `git pull`, it also has some *CLI parameters*.\n\nIt's like if the same big program `git` had several small programs inside.\n\n/// tip\n\nA command looks the same as a *CLI argument*, it's just some name without a preceding `--`. But commands have a predefined name, and are used to group different sets of functionalities into the same CLI application.\n\n///\n\n## Command or subcommand\n\nIt's common to call a CLI program a \"command\".\n\nBut when one of these programs have subcommands, those subcommands are also frequently called just \"commands\".\n\nHave that in mind so you don't get confused.\n\nHere I'll use **CLI application** or **program** to refer to the program you are building in Python with Typer, and **command** to refer to one of these \"subcommands\" of your program.\n\n## A CLI application with multiple commands\n\n**Typer** allows creating CLI applications with multiple commands/subcommands.\n\nNow that you know how to create an explicit `typer.Typer()` application and add one command, let's see how to add multiple commands.\n\nLet's say that we have a CLI application to manage users.\n\nWe'll have a command to `create` users and another command to `delete` them.\n\nTo begin, let's say it can only create and delete one single predefined user:\n\n{* docs_src/commands/index/tutorial002_py310.py hl[6,11] *}\n\nNow we have a CLI application with 2 commands, `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test them\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n\n$ uv run python main.py delete\n\nDeleting user: Hiro Hamada\n\n// Now we have 2 commands! 🎉\n```\n\n</div>\n\nNotice that the help text now shows the 2 commands: `create` and `delete`.\n\n/// tip\n\nBy default, the names of the commands are generated from the function name.\n\n///\n\n## Show the help message if no command is given\n\nBy default, we need to specify `--help` to get the command's help page.\n\nHowever, by setting `no_args_is_help=True` when defining the `typer.Typer()` application, the help function will be shown whenever no argument is given:\n\n{* docs_src/commands/index/tutorial003_py310.py hl[3] *}\n\nNow we can run this:\n\n<div class=\"termy\">\n\n```console\n// Check the help without having to type --help\n$ uv run python main.py\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n```\n\n</div>\n\n\n## Sorting of the commands\n\nNote that by design, **Typer** shows the commands in the order they've been declared.\n\nSo, if we take our original example, with `create` and `delete` commands, and reverse the order in the Python file:\n\n{* docs_src/commands/index/tutorial004_py310.py hl[7,12] *}\n\nThen we will see the `delete` command first in the help output:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  delete\n  create\n```\n\n</div>\n\n## Decorator Technical Details\n\nWhen you use `@app.command()` the function under the decorator is registered in the **Typer** application and is then used later by the application.\n\nBut Typer doesn't modify that function itself, the function is left as is.\n\nThat means that if your function is simple enough that you could create it without using `typer.Option()` or `typer.Argument()`, you could use the same function for a **Typer** application and a **FastAPI** application putting both decorators on top, or similar tricks.\n","isInternal":false,"tokens":1128,"sizeBytes":4827},{"name":"name.md","path":"docs/tutorial/commands/name.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/docs/tutorial/commands/name.md","title":"Command: /name","category":"command-prompt","format":"markdown","content":"# Custom Command Name\n\nBy default, the command names are generated from the function name.\n\nSo, if your function is something like:\n\n```Python\ndef create(username: str): ...\n```\n\nThen the command name will be `create`.\n\nBut if you already had a function called `create()` somewhere in your code, you would have to name your CLI function differently.\n\nAnd what if you wanted the command to still be named `create`?\n\nFor this, you can set the name of the command in the first parameter for the `@app.command()` decorator:\n\n{* docs_src/commands/name/tutorial001_py310.py hl[6,11] *}\n\nNow, even though the functions are named `cli_create_user()` and `cli_delete_user()`, the commands will still be named `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test it\n$ uv run python main.py create Camila\n\nCreating user: Camila\n```\n\n</div>\n\nNote that any underscores in the function name will be replaced with dashes.\n\nSo if your function is something like:\n\n```Python\ndef create_user(username: str): ...\n```\nThen the command name will be `create-user`.\n","isInternal":false,"tokens":319,"sizeBytes":1392},{"name":"one-or-multiple.md","path":"docs/tutorial/commands/one-or-multiple.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/docs/tutorial/commands/one-or-multiple.md","title":"Command: /one-or-multiple","category":"command-prompt","format":"markdown","content":"# One or Multiple Commands\n\nYou might have noticed that if you create a single command, as in the following example:\n\n{* docs_src/typer_app/tutorial001_py310.py hl[3,6,12] *}\n\n**Typer** is smart enough to create a CLI application with that single function as the main CLI application, not as a command/subcommand:\n\n<div class=\"termy\">\n\n```console\n// Without a CLI argument\n$ uv run python main.py\n\nUsage: main.py [OPTIONS] {name}\nTry \"main.py --help\" for help.\n\nError: Missing argument 'name'.\n\n// With the 'name' CLI argument\n$ uv run python main.py Camila\n\nHello Camila\n\n// Asking for help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] {name}\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n```\n\n</div>\n\n/// tip\n\nNotice that it doesn't show a command `main`, even though the function name is `main`.\n\n///\n\nBut if you add multiple commands, **Typer** will create one *CLI command* for each one of them:\n\n{* docs_src/commands/index/tutorial002_py310.py hl[6,11] *}\n\nHere we have 2 commands `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test the commands\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n\n$ uv run python main.py delete\n\nDeleting user: Hiro Hamada\n```\n\n</div>\n\n## One command and one callback\n\nIf you want to create a CLI app with one single command but you still want it to be a command/subcommand you can just add a callback:\n\n{* docs_src/commands/one_or_multiple/tutorial001_py310.py hl[11,12,13] *}\n\nAnd now your CLI program will have a single command.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice the single command create\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// Try it\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n```\n\n</div>\n\n## Using the callback to document\n\nNow that you are using a callback just to have a single command, you might as well use it to add documentation for your app:\n\n{* docs_src/commands/one_or_multiple/tutorial002_py310.py hl[11,12,13,14,15,16,17] *}\n\nAnd now the docstring from the callback will be used as the help text:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n// Notice the help text from the docstring\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Creates a single user Hiro Hamada.\n\n  In the next version it will create 5 more users.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// And it still works the same, the callback does nothing\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n```\n\n</div>\n","isInternal":false,"tokens":847,"sizeBytes":3499},{"name":"options.md","path":"docs/tutorial/commands/options.md","rawUrl":"https://raw.githubusercontent.com/fastapi/typer/HEAD/docs/tutorial/commands/options.md","title":"Command: /options","category":"command-prompt","format":"markdown","content":"# Command CLI Options\n\nCommands can also have their own *CLI options*.\n\nIn fact, each command can have different *CLI arguments* and *CLI options*:\n\n{* docs_src/commands/options/tutorial001_an_py310.py hl[9,15:18,28:30,39] *}\n\nHere we have multiple commands, with different *CLI parameters*:\n\n* `create`:\n    * `username`: a *CLI argument*.\n* `delete`:\n    * `username`: a *CLI argument*.\n    * `--force`: a *CLI option*, if not provided, it's prompted.\n* `delete-all`:\n    * `--force`: a *CLI option*, if not provided, it's prompted.\n* `init`:\n    * Doesn't take any *CLI parameters*.\n\n<div class=\"termy\">\n\n```console\n// Check the help\npython main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n  delete-all\n  init\n```\n\n</div>\n\n/// tip\n\nCheck the command `delete-all`, by default command names are generated from the function name, replacing `_` with `-`.\n\n///\n\nTest it:\n\n<div class=\"termy\">\n\n```console\n// Check the command create\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// Now test the command delete\n$ uv run python main.py delete Camila\n\n# Are you sure you want to delete the user? [y/n]: $ y\n\nDeleting user: Camila\n\n$ uv run python main.py delete Wade\n\n# Are you sure you want to delete the user? [y/n]: $ n\n\nOperation cancelled\n\n// And finally, the command delete-all\n// Notice it doesn't have CLI arguments, only a CLI option\n\n$ uv run python main.py delete-all\n\n# Are you sure you want to delete ALL users? [y/n]: $ y\n\nDeleting all users\n\n$ uv run python main.py delete-all\n\n# Are you sure you want to delete ALL users? [y/n]: $ n\n\nOperation cancelled\n\n// And if you pass the --force CLI option, it doesn't need to confirm\n\n$ uv run python main.py delete-all --force\n\nDeleting all users\n\n// And init that doesn't take any CLI parameter\n$ uv run python main.py init\n\nInitializing user database\n```\n\n</div>\n","isInternal":false,"tokens":542,"sizeBytes":2105}],"systemPromptSnippet":"<yakaai_skills repo=\"fastapi/typer\">\n<!-- File: typer/.agents/skills/typer/SKILL.md (Tokens: ~1677 | Category: anthropic-skill) -->\n---\nname: typer\ndescription: Typer best practices and conventions. Use when working with Typer CLIs. Keeps Typer code clean and up to date with the latest features and patterns, updated with new versions. Write new code or refactor and update old code.\n---\n\n# Typer\n\nOfficial Typer skill to write code with best practices, keeping up to date with new versions and features.\n\n## Installing typer\n\nIn a virtual environment, `pip install typer` (with pip) or `uv pip install typer` (with uv). For your library/project, add `typer` to the dependencies in `pyproject.toml`.\n\nDo not install `typer-slim` or `typer-cli`, they are both deprecated and will now simply install `typer`.\n\nTyper supports Python 3.10 and above.\n\n## Use an explicit `Typer` app\n\nFor maximum generalizability, create an explicit Typer app and register subcommand(s), instead of using `typer.run`:\n\n```python\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef hello():\n    print(f\"Hello World\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\ninstead of:\n\n```python\n# DO NOT DO THIS: Not extensible. Use Typer() instead.\nimport typer\n\n\ndef main():\n    print(f\"Hello World\")\n\n\nif __name__ == \"__main__\":\n    typer.run(main)\n```\n\n## Execute the app\n\nTo execute the app in the terminal, run\n\n```bash\npython main.py\n```\n\nWhen multiple commands are registered to the Typer app, you have to add the command name:\n\n```bash\npython main.py hello\n```\n\nTo see the automatically generated help documentation, run\n\n```bash\npython main.py --help\n```\n\nor set `no_args_is_help` to `True` when creating the `Typer()` add to automatically show the help when running a command without any arguments.\n\n## Use `Annotated`\n\nAlways prefer the `Annotated` style for declarations of CLI arguments and options.\n\nIt allows us to pass additional metadata that can be used by Typer.\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef hello(name: Annotated[str, typer.Argument()] = \"World\"):\n    # Note that name is an optional Argument, as a default is provided\n    print(f\"Hello {name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nThis program can be run as-is, or can provide a specific name:\n\n```bash\npython main.py\npython main.py Rick\n```\n\nAn older way of setting a default value is this:\n```python\n# DO NOT DO THIS: old style. Use Annotated instead.\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=\"World\")):\n    # Note that name is an optional Argument, as a default is provided\n    print(f\"Hello {name}\")\n```\n\nSimilarly, the old style could use ellipsis (...) to explicitly mark an argument as required.\n\n```python\n# DO NOT DO THIS: old style. Use Annotated without a default value instead.\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=...)):\n    # Note that name is now a required Argument\n    print(f\"Hello {name}\")\n```\n\n## CLI Options\n\nCLI options are declared in a similar fashion as arguments, but will be called on the CLI with a single dash (single letter) or 2 dashes (full name).\n\nThe CLI option name is automatically generated from the variable name, so `user_name` becomes `--user-name` automatically:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user_name: Annotated[str, typer.Option()]):\n    # On the CLI, the required user name can be specified with --user-name\n    print(f\"Hello {user_name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nIf you want to specify a different name, or want to add a short version, declare them in the `typer.Option`:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user_name: Annotated[str, typer.Option(\"--name\", \"-n\")]):\n    # On the CLI, the required user name can be specified with -n or --name\n    print(f\"Hello {user_name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nYou can run this program as such:\n\n```bash\npython main.py -n \"Rick\"\npython main.py --name \"Morty\"\n```\n\n### CLI options with multiple values\n\nBy declaring a CLI option as a list, it can receive multiple values:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(user: Annotated[list[str] | None, typer.Option()] = None):\n    if not user:\n        print(f\"No users provided!\")\n        raise typer.Abort()\n    for u in user:\n        print(f\"Processing user: {u}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nThis can be executed like so:\n\n```bash\npython main.py --user Rick --user Morty --user Summer\n```\n\n## Rich\n\nBy default, Rich can be used with its custom markup syntax to set colors and styles, e.g.\n\n```python\nfrom rich import print\n\nprint(\"[bold red]Alert![/bold red] [green]Portal gun[/green] shooting! :boom:\")\n```\n\nTyper supports using Rich formatting in the docstrings and the help messages of CLI arguments and CLI options.\n\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be [green]created[/green]\")\n    ],\n):\n    \"\"\"\n    [bold green]Create[/bold green] a new [italic]shiny[/italic] user. :sparkles:\n\n    This requires a [underline]username[/underline].\n    \"\"\"\n    print(f\"Creating user: {username}\")\n\n\n@app.command(help=\"[bold red]Delete[/bold red] a user with [italic]username[/italic].\")\ndef delete(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be [red]deleted[/red]\")\n    ],\n):\n    \"\"\"\n    Some internal utility function to delete.\n    \"\"\"\n    print(f\"Deleting user: {username}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\nTo disable Rich formatting, set `rich_markup_mode` to `None` when creating a `Typer()` app. By default (when no value is given), Rich formatting is enabled.\n\n### Rich markdown\n\nYou can also set `rich_markup_mode` to `\"markdown\"` to use Markdown in the docstring:\n\n```python\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"markdown\")\n\n\n@app.command(help=\"**Delete** a user with *username*.\")\ndef delete(\n    username: Annotated[\n        str, typer.Argument(help=\"The username to be **deleted** :boom:\")\n    ],\n):\n    print(f\"Deleting user: {username}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\n## Click\n\nOriginally, Typer was built on Click. However, since version 0.26.0, Typer has vendored Click. As such, Click extensions should not be used anymore.\n\nOther settings of `Option` and `Argument` that came from Click but shouldn't be used in Typer anymore, include: `expose_value`, `shell_complete`, `show_choices`, `errors`, `prompt_required`, `is_flag`, `flag_value` and `allow_from_autoenv`.\n\nCode bases using these should be refactored to use pure Typer functionality.\n\n<!-- File: docs/tutorial/commands/arguments.md (Tokens: ~280 | Category: command-prompt) -->\n# Command CLI Arguments\n\nThe same way as with a CLI application with a single command, subcommands (or just \"commands\") can also have their own *CLI arguments*:\n\n{* docs_src/commands/arguments/tutorial001_py310.py hl[7,12] *}\n\n<div class=\"termy\">\n\n```console\n// Check the help for create\n$ uv run python main.py create --help\n\nUsage: main.py create [OPTIONS] {username}\n\nArguments:\n  username  [required]\n\nOptions:\n  --help  Show this message and exit.\n\n// Call it with a CLI argument\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// The same for delete\n$ uv run python main.py delete Camila\n\nDeleting user: Camila\n```\n\n</div>\n\n/// tip\n\nEverything to the *right* of the *command* are *CLI parameters* (*CLI arguments* and *CLI options*) for that command.\n\n///\n\n/// note | Technical Details\n\nActually, it's everything to the right of that command, *before any subcommand*.\n\nIt's possible to have groups of *subcommands*, it's like if one *command* also had *subcommands*. And then those *subcommands* could have their own *CLI parameters*, taking their own *CLI parameters*.\n\nYou will see about them later in another section.\n\n///\n\n<!-- File: docs/tutorial/commands/callback.md (Tokens: ~986 | Category: command-prompt) -->\n# Typer Callback\n\nWhen you create an `app = typer.Typer()` it works as a group of commands.\n\nAnd you can create multiple commands with it.\n\nEach of those commands can have their own *CLI parameters*.\n\nBut as those *CLI parameters* are handled by each of those commands, they don't allow us to create *CLI parameters* for the main CLI application itself.\n\nBut we can use `@app.callback()` for that.\n\nIt's very similar to `@app.command()`, but it declares the *CLI parameters* for the main CLI application (before the commands):\n\n{* docs_src/commands/callback/tutorial001_py310.py hl[25,26,27,28,29,30,31,32] *}\n\nHere we create a `callback` with a `--verbose` *CLI option*.\n\n/// tip\n\nAfter getting the `--verbose` flag, we modify a global `state`, and we use it in the other commands.\n\nThere are other ways to achieve the same, but this will suffice for this example.\n\n///\n\nAnd as we added a docstring to the callback function, by default it will be extracted and used as the help text.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice the main help text, extracted from the callback function: \"Manage users in the awesome CLI app.\"\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Manage users in the awesome CLI app.\n\nOptions:\n  --verbose / --no-verbose  [default: no-verbose]\n  --install-completion      Install completion for the current shell.\n  --show-completion         Show completion for the current shell, to copy it or customize the installation.\n  --help                    Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Check the new top level CLI option --verbose\n\n// Try it normally\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// And now with --verbose\n$ uv run python main.py --verbose create Camila\n\nWill write verbose output\nAbout to create a user\nCreating user: Camila\nJust created a user\n\n// Notice that --verbose belongs to the callback, it has to go before create or delete ⛔️\n$ uv run python main.py create --verbose Camila\n\nUsage: main.py create [OPTIONS] {username}\nTry \"main.py create --help\" for help.\n\nError: No such option: --verbose\n```\n\n</div>\n\n## Adding a callback on creation\n\nIt's also possible to add a callback when creating the `typer.Typer()` app:\n\n{* docs_src/commands/callback/tutorial002_py310.py hl[4,5,8] *}\n\nThat achieves the same as with `@app.callback()`.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\nRunning a command\nCreating user: Camila\n```\n\n</div>\n\n## Overriding a callback\n\nIf you added a callback when creating the `typer.Typer()` app, it's possible to override it with `@app.callback()`:\n\n{* docs_src/commands/callback/tutorial003_py310.py hl[11,12,13] *}\n\nNow `new_callback()` will be the one used.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\n// Notice that the message is the one from new_callback()\nOverride callback, running a command\nCreating user: Camila\n```\n\n</div>\n\n## Adding a callback only for documentation\n\nYou can also add a callback just to add the documentation in the docstring.\n\nIt can be convenient especially if you have several lines of text, as the indentation will be automatically handled for you:\n\n{* docs_src/commands/callback/tutorial004_py310.py hl[8,9,10,11,12,13,14,15,16] *}\n\nNow the callback will be used mainly to extract the docstring for the help text.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n// Notice all the help text extracted from the callback docstring\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Manage users CLI app.\n\n  Use it with the create command.\n\n  A new user with the given 'name' will be created.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// And it just works as normally\n$ uv run python main.py create Camila\n\nCreating user: Camila\n```\n\n</div>\n\n<!-- File: docs/tutorial/commands/context.md (Tokens: ~742 | Category: command-prompt) -->\n# Using the Context\n\nWhen you create a **Typer** application it always has a special, hidden object underneath called the \"Context\".\n\nBut you can access the context by declaring a function parameter of type `typer.Context`.\n\nYou might have read it in [CLI Option Callback and Context](../options/callback-and-context.md).\n\nThe same way, in commands or in the main `Typer` callback you can access the context by declaring a function parameter of type `typer.Context`.\n\n## Getting the context\n\nFor example, let's say that you want to execute some logic in a `Typer` callback depending on the subcommand that is being called.\n\nYou can get the name of the subcommand from the context:\n\n{* docs_src/commands/context/tutorial001_py310.py hl[17,21] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create Camila\n\n// We get the message from the callback\nAbout to execute command: create\nCreating user: Camila\n\n$ uv run python main.py delete Camila\n\n// We get the message from the callback, this time with delete\nAbout to execute command: delete\nDeleting user: Camila\n```\n\n</div>\n\n## Executable callback\n\nBy default, the callback is only executed right before executing a command.\n\nAnd if no command is provided, the help message is shown.\n\nBut we could make it run even without a subcommand with `invoke_without_command=True`:\n\n{* docs_src/commands/context/tutorial002_py310.py hl[16] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py\n\n// The callback is executed, we don't get the default help message\nInitializing database\n\n// Try with a command\n$ uv run python main.py create Camila\n\n// The callback is still executed\nInitializing database\nCreating user: Camila\n```\n\n</div>\n\n## Exclusive executable callback\n\nWe might not want the callback to be executed if there's already other command that will be executed.\n\nFor that, we can get the `typer.Context` and check if there's an invoked command in `ctx.invoked_subcommand`.\n\nIf it's `None`, it means that we are not calling a subcommand but the main program (the callback) directly:\n\n{* docs_src/commands/context/tutorial003_py310.py hl[17,21] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py\n\n// The callback is executed\nInitializing database\n\n// Check it with a subcommand\n$ uv run python main.py create Camila\n\n// This time the callback is not executed\nCreating user: Camila\n```\n\n</div>\n\n## Configuring the context\n\nYou can pass configurations for the context when creating a command or callback.\n\nFor example, you could keep additional *CLI parameters* not declared in your CLI program with `ignore_unknown_options` and `allow_extra_args`.\n\nThen you can access those extra raw *CLI parameters* as a `list` of `str` in `ctx.args`:\n\n{* docs_src/commands/context/tutorial004_py310.py hl[7,9,10] *}\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --name Camila --city Berlin\n\nGot extra arg: --name\nGot extra arg: Camila\nGot extra arg: --city\nGot extra arg: Berlin\n```\n\n</div>\n\n/// tip\n\nNotice that it saves all the extra *CLI parameters* as a raw `list` of `str`, including the *CLI option* names and values, everything together.\n\n///\n\n<!-- File: docs/tutorial/commands/help.md (Tokens: ~7372 | Category: command-prompt) -->\n# Command Help\n\nThe same as before, you can add help for the commands in the docstrings and the *CLI options*.\n\nAnd the `typer.Typer()` application receives a parameter `help` that you can pass with the main help text for your CLI program:\n\n{* docs_src/commands/help/tutorial001_an_py310.py hl[5,10:12,23,27:31,44,48:52,61:63] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the new help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Awesome CLI user manager.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create      Create a new user with username.\n  delete      Delete a user with username.\n  delete-all  Delete ALL users in the database.\n  init        Initialize the users database.\n\n// Now the commands have inline help 🎉\n\n// Check the help for create\n$ uv run python main.py create --help\n\nUsage: main.py create [OPTIONS] {username}\n\n  Create a new user with username.\n\nArguments:\n  username  [required]\n\nOptions:\n  --help  Show this message and exit.\n\n// Check the help for delete\n$ uv run python main.py delete --help\n\nUsage: main.py delete [OPTIONS] {username}\n\n  Delete a user with username.\n\n  If --force is not used, will ask for confirmation.\n\nArguments:\n  username  [required]\n\nOptions:\n  --force / --no-force  Force deletion without confirmation.  [required]\n  --help                Show this message and exit.\n\n// Check the help for delete-all\n$ uv run python main.py delete-all --help\n\nUsage: main.py delete-all [OPTIONS]\n\n  Delete ALL users in the database.\n\n  If --force is not used, will ask for confirmation.\n\nOptions:\n  --force / --no-force  Force deletion without confirmation.  [required]\n  --help                Show this message and exit.\n\n// Check the help for init\n$ uv run python main.py init --help\n\nUsage: main.py init [OPTIONS]\n\n  Initialize the users database.\n\nOptions:\n  --help  Show this message and exit.\n```\n\n</div>\n\n/// tip\n\n`typer.Typer()` receives several other parameters for other things, we'll see that later.\n\nYou will also see how to use \"Callbacks\" later, and those include a way to add this same help message in a function docstring.\n\n///\n\n## Overwrite command help\n\nYou will probably be better adding the help text as a docstring to your functions, but if for some reason you wanted to overwrite it, you can use the `help` function argument passed to `@app.command()`:\n\n{* docs_src/commands/help/tutorial002_py310.py hl[6,14] *}\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice it uses the help passed to @app.command()\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy\n                        it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create  Create a new user with username.\n  delete  Delete a user with username.\n\n// It uses \"Create a new user with username.\" instead of \"Some internal utility function to create.\"\n```\n\n</div>\n\n## Deprecate a Command\n\nThere could be cases where you have a command in your app that you need to deprecate, so that your users stop using it, even while it's still supported for a while.\n\nYou can mark it with the parameter `deprecated=True`:\n\n{* docs_src/commands/help/tutorial003_py310.py hl[14] *}\n\nAnd when you show the `--help` option you will see it's marked as \"`deprecated`\":\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                  </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create       </b></font> Create a user.                                      │\n<font color=\"#A5A5A1\">│ </font><font color=\"#6B9F98\"><b>delete       </b></font> Delete a user.              <font color=\"#F92672\">(deprecated)           </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd if you check the `--help` for the deprecated command (in this example, the command `delete`), it also shows it as deprecated:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                  </b>\n<b>                                                                     </b>\n <font color=\"#F92672\">(deprecated) </font>\n Delete a user.\n This is deprecated and will stop being supported soon.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  <font color=\"#A6194C\">[required]</font>                              │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n## Suggest Commands\n\nAs of version 0.20.0, Typer added support for suggesting mistyped command names. This feature is **enabled by default**, but you can disable it with the parameter `suggest_commands=False`:\n\n{* docs_src/commands/index/tutorial005_py310.py hl[3] *}\n\nIf a user mistypes a command, they'll see a helpful suggestion:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py crate\n\n<font color=\"#C4A000\">Usage: </font>main.py [OPTIONS] COMMAND [ARGS]...\n<font color=\"#AAAAAA\">Try </font><font color=\"#22436D\">&apos;main.py </font><font color=\"#4C6A8A\"><b>--help</b></font><font color=\"#22436D\">&apos;</font><font color=\"#AAAAAA\"> for help.</font>\n<font color=\"#CC0000\">╭─ Error ───────────────────────────────────────────────────────────╮</font>\n<font color=\"#CC0000\">│</font> No such command &apos;crate&apos;. Did you mean &apos;create&apos;?                   <font color=\"#CC0000\">│</font>\n<font color=\"#CC0000\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nIf there are multiple close matches, Typer will suggest them all. This feature uses Python's built-in `difflib.get_close_matches()` to find similar command names, making your CLI more user-friendly by helping users recover from typos.\n\n## Rich Markdown and Markup\n\nTyper installs **Rich** to allow for more formatting in the docstrings and the `help` parameter for *CLI arguments* and *CLI options*. You will see more about it below. 👇\n\n/// note\n\nYou can disable rich text formatting by setting `rich_markup_mode` to `None` for your specific app.\nAlternatively, you can disable it globally using an environmental variable `TYPER_USE_RICH` set to `False` or `0`.\n\n///\n\n### Rich Markup\n\nIf you set `rich_markup_mode=\"rich\"` when creating the `typer.Typer()` app (which is the default), you will be able to use [Rich Console Markup](https://rich.readthedocs.io/en/stable/markup.html) in the docstring, and even in the help for the *CLI arguments* and options:\n\n{* docs_src/commands/help/tutorial004_an_py310.py hl[5,11,15:17,22,25,28] *}\n\nWith that, you can use [Rich Console Markup](https://rich.readthedocs.io/en/stable/markup.html) to format the text in the docstring for the command `create`, make the word \"`create`\" bold and green, and even use an [emoji](https://rich.readthedocs.io/en/stable/markup.html#emoji).\n\nYou can also use markup in the help for the `username` CLI Argument.\n\nAnd the same as before, the help text overwritten for the command `delete` can also use Rich Markup, the same in the CLI Argument and CLI Option.\n\nIf you run the program and check the help, you will see that **Typer** uses **Rich** internally to format the help.\n\nCheck the help for the `create` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username}                   </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\"><b>Create</b></font> a new <i>shiny</i> user. ✨\n This requires a <font color=\"#A5A5A1\"><u style=\"text-decoration-style:single\">username</u></font><font color=\"#A5A5A1\">.                                           </font>\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <font color=\"#A6E22E\">created</font>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                </font>               │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd check the help for the `delete` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <font color=\"#F92672\"><b>Delete</b></font> a user with <i>username</i>.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <font color=\"#F92672\">deleted</font>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                </font>               │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the <font color=\"#F92672\"><b>deletion</b></font> 💥                  │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n### Rich Markdown\n\nIf you set `rich_markup_mode=\"markdown\"` when creating the `typer.Typer()` app, you will be able to use Markdown in the docstring:\n\n{* docs_src/commands/help/tutorial005_an_py310.py hl[5,10,13:21,26,28:29] *}\n\nWith that, you can use Markdown to format the text in the docstring for the command `create`, make the word \"`create`\" bold, show a list of items, and even use an [emoji](https://rich.readthedocs.io/en/stable/markup.html#emoji).\n\nAnd the same as before, the help text overwritten for the command `delete` can also use Markdown.\n\nCheck the help for the `create` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <b>Create</b> a new <i>shiny</i> user. ✨\n\n <font color=\"#F4BF75\"><b> • </b></font><font color=\"#A5A5A1\">Create a username                                                </font>\n <font color=\"#F4BF75\"><b> • </b></font><font color=\"#A5A5A1\">Show that the username is created                                </font>\n\n <font color=\"#F4BF75\">───────────────────────────────────────────────────────────────────</font>\n Learn more at the <font color=\"#44919F\">Typer docs website</font>\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <b>created</b>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                              </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>          Show this message and exit.                       │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd the same for the `delete` command:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py delete --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py delete [OPTIONS] {username}                     </b>\n<b>                                                                     </b>\n <b>Delete</b> a user with <i>username</i>.\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to be <b>deleted</b>              │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]                              </font> │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the <b>deletion</b> 💥                  │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n/// note\n\nNotice that in Markdown you cannot define colors. For colors you might prefer to use Rich markup.\n\n///\n\n## Help Panels\n\nIf you have many commands or CLI parameters, you might want to show their documentation in different panels when using the `--help` option.\n\nIf you installed [Rich](https://rich.readthedocs.io/) as described in [Printing and Colors](../printing.md), you can configure the panel to use for each command or CLI parameter.\n\n### Help Panels for Commands\n\nTo set the panel for a command you can pass the argument `rich_help_panel` with the name of the panel you want to use:\n\n{* docs_src/commands/help/tutorial006_py310.py hl[22,30,38,46] *}\n\nCommands without a panel will be shown in the default panel `Commands`, and the rest will be shown in the next panels:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                   </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create          </b></font> <font color=\"#A6E22E\">Create</font> a new user. ✨                            │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>delete          </b></font> <font color=\"#F92672\">Delete</font> a user. ❌                                │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Utils and Configs ───────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>config  </b></font> <font color=\"#66D9EF\">Configure</font> the system. ⚙                                 │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>sync    </b></font> <font color=\"#66D9EF\">Synchronize</font> the system or something fancy like that. ♻  │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Help and Others ─────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>help         </b></font> Get <font color=\"#F4BF75\">help</font> with the system. ❓                        │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>report       </b></font> <font color=\"#F4BF75\">Report</font> an issue. ❗                                 │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\n### Help Panels for CLI Parameters\n\nThe same way, you can configure the panels for *CLI arguments* and *CLI options* with `rich_help_panel`.\n\nAnd of course, in the same application you can also set the `rich_help_panel` for commands.\n\n{* docs_src/commands/help/tutorial007_an_py310.py hl[14,20,26,36] *}\n\nThen if you run the application you will see all the *CLI parameters* in their respective panels.\n\n* First the ***CLI arguments*** that don't have a panel name set in a **default** one named \"`Arguments`\".\n* Next the ***CLI arguments*** with a **custom panel**. In this example named \"`Secondary Arguments`\".\n* After that, the ***CLI options*** that don't have a panel in a **default** one named \"`Options`\".\n* And finally, the ***CLI options*** with a **custom panel** set. In this example named \"`Additional Data`\".\n\nYou can check the `--help` option for the command `create`:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py create --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py create [OPTIONS] {username} [lastname]          </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\">Create</font> a new user. ✨\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>  The username to create                  │\n<font color=\"#A5A5A1\">│                          </font><font color=\"#A6194C\">[required]            </font>                   │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Secondary Arguments ─────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│   lastname      </font><font color=\"#A37F4E\"><b>lastname</b></font>  The last name of the new user           │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--force</b></font>    <font color=\"#AE81FF\"><b>--no-force</b></font>      Force the creation of the user         │\n<font color=\"#A5A5A1\">│                            [default: no-force]                    │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                     Show this message and exit.            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Additional Data ─────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--age</b></font>                   <font color=\"#F4BF75\"><b>&lt;int&gt;   </b></font>  The age of the new user         │\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--favorite-color</b></font>        <font color=\"#F4BF75\"><b>&lt;str&gt;   </b></font>  The favorite color of the new   │\n<font color=\"#A5A5A1\">│                                  user                             │</font>\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nAnd of course, the `rich_help_panel` can be used in the same way for commands in the same application.\n\nAnd those panels will be shown when you use the main `--help` option.\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] COMMAND [ARGS]...                   </b>\n<b>                                                                     </b>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Commands ────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>create          </b></font> <font color=\"#A6E22E\">Create</font> a new user. ✨                            │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Utils and Configs ───────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>config         </b></font> <font color=\"#66D9EF\">Configure</font> the system. ⚙                          │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n```\n\n</div>\n\nYou can see the custom panel for the commands for \"`Utils and Configs`\".\n\n## Epilog\n\nIf you need, you can also add an epilog section to the help of your commands:\n\n{* docs_src/commands/help/tutorial008_py310.py hl[6] *}\n\nAnd when you check the `--help` option it will look like:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n<b> </b><font color=\"#F4BF75\"><b>Usage: </b></font><b>main.py [OPTIONS] {username}                            </b>\n<b>                                                                     </b>\n <font color=\"#A6E22E\">Create</font> a new user. ✨\n\n<font color=\"#A5A5A1\">╭─ Arguments ───────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#F92672\">*</font>    username      <font color=\"#F4BF75\"><b>&lt;str&gt;</b></font>                  <font color=\"#A6194C\">[required]</font>              │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n<font color=\"#A5A5A1\">╭─ Options ─────────────────────────────────────────────────────────╮</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--install-completion</b></font>          Install completion for the current  │\n<font color=\"#A5A5A1\">│                               shell.                              │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--show-completion</b></font>             Show completion for the current     │\n<font color=\"#A5A5A1\">│                               shell, to copy it or customize the  │</font>\n<font color=\"#A5A5A1\">│                               installation.                       │</font>\n<font color=\"#A5A5A1\">│ </font><font color=\"#A1EFE4\"><b>--help</b></font>                        Show this message and exit.         │\n<font color=\"#A5A5A1\">╰───────────────────────────────────────────────────────────────────╯</font>\n\n Made with ❤ in <font color=\"#66D9EF\">Venus</font>\n```\n\n</div>\n\n<!-- File: docs/tutorial/commands/index.md (Tokens: ~1128 | Category: command-prompt) -->\n# Commands\n\nWe have seen how to create a CLI program with possibly several *CLI options* and *CLI arguments*.\n\nBut **Typer** allows you to create CLI programs with several commands (also known as subcommands).\n\nFor example, the program `git` has several commands.\n\nOne command of `git` is `git push`. And `git push` in turn takes its own *CLI arguments* and *CLI options*.\n\nFor example:\n\n<div class=\"termy\">\n\n```console\n// The push command with no parameters\n$ git push\n\n---> 100%\n\n// The push command with one CLI option --set-upstream and 2 CLI arguments\n$ git push --set-upstream origin master\n\n---> 100%\n```\n\n</div>\n\nAnother command of `git` is `git pull`, it also has some *CLI parameters*.\n\nIt's like if the same big program `git` had several small programs inside.\n\n/// tip\n\nA command looks the same as a *CLI argument*, it's just some name without a preceding `--`. But commands have a predefined name, and are used to group different sets of functionalities into the same CLI application.\n\n///\n\n## Command or subcommand\n\nIt's common to call a CLI program a \"command\".\n\nBut when one of these programs have subcommands, those subcommands are also frequently called just \"commands\".\n\nHave that in mind so you don't get confused.\n\nHere I'll use **CLI application** or **program** to refer to the program you are building in Python with Typer, and **command** to refer to one of these \"subcommands\" of your program.\n\n## A CLI application with multiple commands\n\n**Typer** allows creating CLI applications with multiple commands/subcommands.\n\nNow that you know how to create an explicit `typer.Typer()` application and add one command, let's see how to add multiple commands.\n\nLet's say that we have a CLI application to manage users.\n\nWe'll have a command to `create` users and another command to `delete` them.\n\nTo begin, let's say it can only create and delete one single predefined user:\n\n{* docs_src/commands/index/tutorial002_py310.py hl[6,11] *}\n\nNow we have a CLI application with 2 commands, `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test them\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n\n$ uv run python main.py delete\n\nDeleting user: Hiro Hamada\n\n// Now we have 2 commands! 🎉\n```\n\n</div>\n\nNotice that the help text now shows the 2 commands: `create` and `delete`.\n\n/// tip\n\nBy default, the names of the commands are generated from the function name.\n\n///\n\n## Show the help message if no command is given\n\nBy default, we need to specify `--help` to get the command's help page.\n\nHowever, by setting `no_args_is_help=True` when defining the `typer.Typer()` application, the help function will be shown whenever no argument is given:\n\n{* docs_src/commands/index/tutorial003_py310.py hl[3] *}\n\nNow we can run this:\n\n<div class=\"termy\">\n\n```console\n// Check the help without having to type --help\n$ uv run python main.py\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n```\n\n</div>\n\n\n## Sorting of the commands\n\nNote that by design, **Typer** shows the commands in the order they've been declared.\n\nSo, if we take our original example, with `create` and `delete` commands, and reverse the order in the Python file:\n\n{* docs_src/commands/index/tutorial004_py310.py hl[7,12] *}\n\nThen we will see the `delete` command first in the help output:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  delete\n  create\n```\n\n</div>\n\n## Decorator Technical Details\n\nWhen you use `@app.command()` the function under the decorator is registered in the **Typer** application and is then used later by the application.\n\nBut Typer doesn't modify that function itself, the function is left as is.\n\nThat means that if your function is simple enough that you could create it without using `typer.Option()` or `typer.Argument()`, you could use the same function for a **Typer** application and a **FastAPI** application putting both decorators on top, or similar tricks.\n\n<!-- File: docs/tutorial/commands/name.md (Tokens: ~319 | Category: command-prompt) -->\n# Custom Command Name\n\nBy default, the command names are generated from the function name.\n\nSo, if your function is something like:\n\n```Python\ndef create(username: str): ...\n```\n\nThen the command name will be `create`.\n\nBut if you already had a function called `create()` somewhere in your code, you would have to name your CLI function differently.\n\nAnd what if you wanted the command to still be named `create`?\n\nFor this, you can set the name of the command in the first parameter for the `@app.command()` decorator:\n\n{* docs_src/commands/name/tutorial001_py310.py hl[6,11] *}\n\nNow, even though the functions are named `cli_create_user()` and `cli_delete_user()`, the commands will still be named `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test it\n$ uv run python main.py create Camila\n\nCreating user: Camila\n```\n\n</div>\n\nNote that any underscores in the function name will be replaced with dashes.\n\nSo if your function is something like:\n\n```Python\ndef create_user(username: str): ...\n```\nThen the command name will be `create-user`.\n\n<!-- File: docs/tutorial/commands/one-or-multiple.md (Tokens: ~847 | Category: command-prompt) -->\n# One or Multiple Commands\n\nYou might have noticed that if you create a single command, as in the following example:\n\n{* docs_src/typer_app/tutorial001_py310.py hl[3,6,12] *}\n\n**Typer** is smart enough to create a CLI application with that single function as the main CLI application, not as a command/subcommand:\n\n<div class=\"termy\">\n\n```console\n// Without a CLI argument\n$ uv run python main.py\n\nUsage: main.py [OPTIONS] {name}\nTry \"main.py --help\" for help.\n\nError: Missing argument 'name'.\n\n// With the 'name' CLI argument\n$ uv run python main.py Camila\n\nHello Camila\n\n// Asking for help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] {name}\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n```\n\n</div>\n\n/// tip\n\nNotice that it doesn't show a command `main`, even though the function name is `main`.\n\n///\n\nBut if you add multiple commands, **Typer** will create one *CLI command* for each one of them:\n\n{* docs_src/commands/index/tutorial002_py310.py hl[6,11] *}\n\nHere we have 2 commands `create` and `delete`:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n\n// Test the commands\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n\n$ uv run python main.py delete\n\nDeleting user: Hiro Hamada\n```\n\n</div>\n\n## One command and one callback\n\nIf you want to create a CLI app with one single command but you still want it to be a command/subcommand you can just add a callback:\n\n{* docs_src/commands/one_or_multiple/tutorial001_py310.py hl[11,12,13] *}\n\nAnd now your CLI program will have a single command.\n\nCheck it:\n\n<div class=\"termy\">\n\n```console\n// Check the help\n$ uv run python main.py --help\n\n// Notice the single command create\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// Try it\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n```\n\n</div>\n\n## Using the callback to document\n\nNow that you are using a callback just to have a single command, you might as well use it to add documentation for your app:\n\n{* docs_src/commands/one_or_multiple/tutorial002_py310.py hl[11,12,13,14,15,16,17] *}\n\nAnd now the docstring from the callback will be used as the help text:\n\n<div class=\"termy\">\n\n```console\n$ uv run python main.py --help\n\n// Notice the help text from the docstring\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\n  Creates a single user Hiro Hamada.\n\n  In the next version it will create 5 more users.\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n\n// And it still works the same, the callback does nothing\n$ uv run python main.py create\n\nCreating user: Hiro Hamada\n```\n\n</div>\n\n<!-- File: docs/tutorial/commands/options.md (Tokens: ~542 | Category: command-prompt) -->\n# Command CLI Options\n\nCommands can also have their own *CLI options*.\n\nIn fact, each command can have different *CLI arguments* and *CLI options*:\n\n{* docs_src/commands/options/tutorial001_an_py310.py hl[9,15:18,28:30,39] *}\n\nHere we have multiple commands, with different *CLI parameters*:\n\n* `create`:\n    * `username`: a *CLI argument*.\n* `delete`:\n    * `username`: a *CLI argument*.\n    * `--force`: a *CLI option*, if not provided, it's prompted.\n* `delete-all`:\n    * `--force`: a *CLI option*, if not provided, it's prompted.\n* `init`:\n    * Doesn't take any *CLI parameters*.\n\n<div class=\"termy\">\n\n```console\n// Check the help\npython main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion  Install completion for the current shell.\n  --show-completion     Show completion for the current shell, to copy it or customize the installation.\n  --help                Show this message and exit.\n\nCommands:\n  create\n  delete\n  delete-all\n  init\n```\n\n</div>\n\n/// tip\n\nCheck the command `delete-all`, by default command names are generated from the function name, replacing `_` with `-`.\n\n///\n\nTest it:\n\n<div class=\"termy\">\n\n```console\n// Check the command create\n$ uv run python main.py create Camila\n\nCreating user: Camila\n\n// Now test the command delete\n$ uv run python main.py delete Camila\n\n# Are you sure you want to delete the user? [y/n]: $ y\n\nDeleting user: Camila\n\n$ uv run python main.py delete Wade\n\n# Are you sure you want to delete the user? [y/n]: $ n\n\nOperation cancelled\n\n// And finally, the command delete-all\n// Notice it doesn't have CLI arguments, only a CLI option\n\n$ uv run python main.py delete-all\n\n# Are you sure you want to delete ALL users? [y/n]: $ y\n\nDeleting all users\n\n$ uv run python main.py delete-all\n\n# Are you sure you want to delete ALL users? [y/n]: $ n\n\nOperation cancelled\n\n// And if you pass the --force CLI option, it doesn't need to confirm\n\n$ uv run python main.py delete-all --force\n\nDeleting all users\n\n// And init that doesn't take any CLI parameter\n$ uv run python main.py init\n\nInitializing user database\n```\n\n</div>\n</yakaai_skills>"}