Usage

rich-prompt provides interactive terminal prompts. Users can navigate and select from a list of options.

All prompt classes follow the same API of rich.prompt.Prompt.

Prompts

Call the instance for a reusable prompt, or use the .ask() class method for a one-off prompt.

from richer_prompt import Select

# Reusable prompt instance
select_color = Select("Select a color:", choices=["Red", "Green", "Blue"])
choice = select_color()

# One-off prompt
choice = Select.ask("Select a color:", choices=["Red", "Green", "Blue"])
select Select a color: 1. Red 2. Green 3. Blue ↑↓ to navigate · Enter to select

The prompt message may be given as a string (which may contain Console Markup and emoji code) or as a rich.text.Text instance.

Select.ask("[cyan]?[/cyan] Select a [i]color[/i]:", choices=["Red", "Green", "Blue"])
select ? Select a color: 1. Red 2. Green 3. Blue ↑↓ to navigate · Enter to select

See the API Reference for details on each prompt class and their available options.

Interactivity

Prompts read single keystrokes, so they require an interactive terminal. When standard input is not a TTY (for example a pipe or a CI job), prompts raise richer_prompt.NotInteractiveError before rendering anything.

  • Arrow keys (or vi-like keybindings k, j, etc) to move the cursor.

  • Home/End jump to the first/last option.

  • Tab/Shift+Tab to switch tabs in Tabs.

While a prompt is running:

  • Ctrl+C raises KeyboardInterrupt.

  • Ctrl+D (or Ctrl+Z on Windows) raises EOFError.

Handle both as you would for any other input() call.

Choices

Use Choice objects in the choices list for more control over the display and formatting.

  • Choice.value is the actual value returned when the choice is selected (can be any type that implements __str__).

  • Choice.label replaces the text in the prompt display. (optional)

  • Choice.description adds secondary text to the choice. (optional)

from richer_prompt import Choice, Tabs

Tabs.ask(
    "Do you want to continue?",
    choices=[
        Choice(False, label="No", description="Cancel and exit"),
        Choice(True, label="Yes", description="This action cannot be undone"),
    ]
)
tabs Do you want to continue?  No  Yes  → Cancel and exit

Themes

Prompts are styled with Rich themes. When a prompt runs, any richer_prompt.* style defined in the console’s theme overrides the default style; all other style names fall back to the defaults listed below, no matter when the theme was created.

from rich.console import Console
from rich.theme import Theme

from richer_prompt import MultiSelect

theme = Theme({"richer_prompt.cursor": "blue bold", "richer_prompt.hint": "yellow italic"})
console = Console(theme=theme)

MultiSelect.ask(
    "Select multiple options:",
    choices=["Option 1", "Option 2", "Option 3"],
    console=console
)
multiselect Select multiple options: 1. [ ]Option 1 2. [ ]Option 2 3. [ ]Option 3 Submit ↑↓ to navigate · Enter to select · Submit to finish

The following style names are available for customization:

richer-prompt style names

Style name

Default style

Description

richer_prompt.title

bold

Prompt title text.

richer_prompt.description

dim

Prompt description text displayed under the title.

richer_prompt.hint

dim

Hint text shown at the bottom of prompts.

richer_prompt.choice

null

Base style for choice labels.

richer_prompt.cursor

magenta

Active cursor indicator for the current option.

richer_prompt.checkbox

null

Base style for checkbox markers in multiselect prompts.

richer_prompt.checkbox.checked

green

Checkbox marker style for selected items.

richer_prompt.tab

null

Base style for tab labels.

richer_prompt.tab.active

magenta reverse

Style for the currently active tab.

Testing

Use richer_prompt.testing.simulate_keys() to test code that runs prompts. Prompts inside the block read the given keys instead of the real keyboard, so no interactive terminal is required.

from richer_prompt import keys, Select
from richer_prompt.testing import simulate_keys

select_color = Select("Choose a color:", ["Red", "Green", "Blue"])

with simulate_keys(keys.DOWN, keys.ENTER):
    assert select_color() == "Green"

If the keys run out while a prompt is still waiting for input, the key read raises AssertionError. Control keys behave like the real keyboard: keys.CTRL_C raises KeyboardInterrupt and keys.CTRL_D raises EOFError.