Skip to main content

Rich Help Integration

Typer integrates with the Rich library to provide visually enhanced CLI help pages, formatted error messages, and pretty exception tracebacks. This integration is primarily managed through the Typer entry point and the underlying TyperCommand and TyperGroup classes.

Rich Help Panels

One of the most powerful features of the Rich integration is the ability to group commands, arguments, and options into visual panels. By default, Typer groups these into "Arguments", "Options", and "Commands" panels. You can customize this by using the rich_help_panel parameter.

Grouping Commands

When creating a multi-command application, you can group related subcommands into named panels using the @app.command() decorator.

import typer

app = typer.Typer()

@app.command(rich_help_panel="User Management")
def create(name: str):
"""Create a new user."""
print(f"Creating user: {name}")

@app.command(rich_help_panel="User Management")
def delete(name: str):
"""Delete a user."""
print(f"Deleting user: {name}")

@app.command(rich_help_panel="System Utils")
def config():
"""Configure the system."""
print("Configuring...")

In this example, create and delete will appear inside a panel titled "User Management", while config will appear in "System Utils".

Grouping Arguments and Options

Similarly, you can group parameters within a single command's help page using typer.Argument or typer.Option.

@app.command()
def sync(
source: str = typer.Argument(..., rich_help_panel="Locations"),
dest: str = typer.Argument(..., rich_help_panel="Locations"),
verbose: bool = typer.Option(False, rich_help_panel="Logging"),
):
"""Sync files from source to destination."""
...

The rich_utils.rich_format_help function in typer/rich_utils.py handles the logic of collecting these parameters and rendering them into rich.panel.Panel objects.

Markdown and Rich Markup

Typer can parse your docstrings and help text as either Rich Markup or Markdown. This is controlled by the rich_markup_mode parameter in the Typer constructor or individual command decorators.

The available modes are:

  • "rich": (Default if Rich is installed) Supports Rich's square-bracket syntax (e.g., [bold]text[/bold]).
  • "markdown": Supports standard Markdown syntax (e.g., **bold**).
  • None: Disables Rich formatting for help text.

Using Rich Markup

app = typer.Typer(rich_markup_mode="rich")

@app.command()
def deploy():
"""
Deploy the application to [bold magenta]production[/bold magenta].

Check the [link=https://example.com]docs[/link] for more info.
"""
...

Using Markdown

app = typer.Typer(rich_markup_mode="markdown")

@app.command()
def build():
"""
Build the project.

* Compiles source
* Runs tests
* Generates artifacts
"""
...

The implementation in typer/rich_utils.py uses inspect.cleandoc() to handle indentation and rich.markdown.Markdown or rich.text.Text.from_markup() to render the content.

Pretty Exceptions

Typer uses Rich to format Python tracebacks, making them easier to read during development. This behavior is configured on the Typer app instance:

  • pretty_exceptions_enable: Set to False to revert to standard Python tracebacks.
  • pretty_exceptions_show_locals: Set to True to display the values of local variables in the traceback (useful for debugging but potentially sensitive).
  • pretty_exceptions_short: Set to False to show the full stack trace instead of the simplified version.
app = typer.Typer(
pretty_exceptions_enable=True,
pretty_exceptions_show_locals=True,
pretty_exceptions_short=True,
)

When an exception occurs, the Typer.__call__ method catches it and attaches a DeveloperExceptionConfig object to the exception. The custom except_hook in typer/main.py then uses rich.traceback.Traceback to render the error.

Customizing Styles

The visual appearance of the Rich output is defined by several constants in typer/rich_utils.py. While these are not directly exposed as configuration objects, they define the default look and feel:

  • STYLE_OPTION: "bold cyan" (for option names)
  • STYLE_METAVAR: "bold yellow" (for argument placeholders)
  • STYLE_USAGE: "yellow" (for the usage string)
  • STYLE_COMMANDS_PANEL_BORDER: "dim" (for the border of command panels)

These styles are applied via a rich.theme.Theme in the _get_rich_console function, ensuring a consistent visual language across the CLI.

Core Implementation Classes

The Rich integration is baked into the core command classes:

  • TyperCommand: Overrides format_help to call rich_utils.rich_format_help. It stores the rich_markup_mode and rich_help_panel for individual commands.
  • TyperGroup: Inherits from TyperCommand and handles the rendering of subcommands into panels. It also provides command suggestions (e.g., "Did you mean...?") using Rich formatting when a user mistypes a command.