This page documents the prompt subsystem located in rich/prompt.py which provides interactive user input with validation, type coercion, default values, choices, and password masking. For general console input via console.input(), see Console. For the markup and styling system that controls how prompt text is rendered, see Markup and Formatting.
The rich.prompt module provides a class hierarchy for asking users for typed input in a terminal loop. The loop repeats until the user supplies a valid response, printing an error message for each invalid attempt. All prompt classes ultimately call Console.input() to read from the terminal.
Class hierarchy:
Sources: rich/prompt.py30-401
| Class | Module | Return Type | Description |
|---|---|---|---|
PromptBase | rich.prompt | PromptType (generic) | Abstract base; extend this for custom prompts |
Prompt | rich.prompt | str | Standard string prompt |
IntPrompt | rich.prompt | int | Integer prompt; rejects non-numeric input |
FloatPrompt | rich.prompt | float | Float prompt; rejects non-numeric input |
Confirm | rich.prompt | bool | Yes/no prompt; accepts y or n only |
Sources: rich/prompt.py304-363
ask() ShortcutEvery prompt class exposes a classmethod ask() that constructs the prompt, runs the loop, and returns the result in a single call. This is the most common usage pattern.
name = Prompt.ask("Enter your name")
count = IntPrompt.ask("How many items", default=1)
temp = FloatPrompt.ask("Enter temperature")
confirmed = Confirm.ask("Continue?", default=True)
ask() accepts the same parameters as __init__() plus a default and stream argument. Internally it instantiates the class and calls __call__().
Sources: rich/prompt.py111-149
All parameters apply to PromptBase.__init__() and are forwarded from ask().
| Parameter | Type | Default | Description |
|---|---|---|---|
prompt | str or Text | "" | Prompt text; markup is parsed if a plain string |
console | Console or None | None | Console to use; falls back to the global console |
password | bool | False | Masks input characters (passed to console.input()) |
choices | List[str] or None | None | Restricts valid responses to these values |
case_sensitive | bool | True | Whether choice matching is case-sensitive |
show_default | bool | True | Appends default value to displayed prompt |
show_choices | bool | True | Appends choices list to displayed prompt |
Sources: rich/prompt.py54-76
Prompt execution flow:
Sources: rich/prompt.py280-301
The loop is implemented in PromptBase.__call__() rich/prompt.py280-301 Key steps:
pre_prompt() — No-op hook; override in subclasses to print something before the prompt appears.make_prompt(default) — Assembles the displayable Text object, appending choices and default in styled form.get_input(...) — Delegates to console.input(prompt, password=password, stream=stream).process_response().process_response(value) — Strips, converts (using response_type), and validates the string against the choices list.InvalidResponse — If raised, on_validate_error() prints the error and the loop restarts.How the prompt text is assembled in make_prompt():
The resulting prompt for Prompt.ask("what is your name", choices=["foo","bar"], default="baz") looks like:
what is your name [foo/bar] (baz):
The make_prompt() method rich/prompt.py162-191 builds this as a single Text object with multiple spans, each carrying a named style.
Sources: rich/prompt.py162-191
InvalidResponseException hierarchy:
InvalidResponse rich/prompt.py15-27 is the primary validation signal. Raise it inside a custom process_response() override with a message that will be printed to the console.
PromptBase.process_response() raises InvalidResponse in two situations:
response_type (e.g., typing "foo" into an IntPrompt).choices list (when choices are defined).The on_validate_error() method rich/prompt.py258-265 prints the error using console.print(error, markup=True), which triggers InvalidResponse.__rich__() to return the styled message text.
Sources: rich/prompt.py15-27 rich/prompt.py227-265
When choices is provided, check_choice() rich/prompt.py213-225 validates the user's input against the list.
case_sensitive=False): lowercased comparison; the original choice string (not the user's input) is returned.# Case-sensitive (default)
Prompt.ask("Pick one", choices=["Apple", "Banana"])
# Case-insensitive: "apple" or "APPLE" both return "Apple"
Prompt.ask("Pick one", choices=["Apple", "Banana"], case_sensitive=False)
Sources: rich/prompt.py213-256 tests/test_prompt.py24-39
default=<value> to ask() or __call__().... (Ellipsis). A default of ... means the prompt is required.process_response() is not called on it.show_default=True (the default) causes render_default() to append the default value in parentheses using the prompt.default style.Confirm overrides render_default() rich/prompt.py353-356 to display (y) or (n) instead of True/False.Sources: rich/prompt.py151-191 rich/prompt.py280-301
Setting password=True passes the flag directly to console.input(), which uses Python's getpass mechanism to mask the typed characters. The prompt text is still displayed normally.
secret = Prompt.ask("Enter password", password=True)
Sources: rich/prompt.py54-76 rich/prompt.py194-211
Confirm in DetailConfirm rich/prompt.py340-363 is a specialised subclass with fixed choices ["y", "n"]. Its process_response() is overridden to:
InvalidResponse if the value is not exactly "y" or "n".True if the value equals choices[0] ("y"), otherwise False.The displayed prompt looks like: Continue? [y/n] (y): when default=True.
Sources: rich/prompt.py340-363 tests/test_prompt.py73-126
The prompt system uses named styles from the Rich theme. These can be overridden in a custom Theme.
| Style Name | Applied To |
|---|---|
prompt | The main prompt text |
prompt.choices | The [choice1/choice2] choices display |
prompt.default | The (default_value) display |
prompt.invalid | Type validation error messages |
prompt.invalid.choice | Invalid choice error messages |
Sources: rich/prompt.py44-50 rich/prompt.py162-191
PromptBase is designed to be subclassed. Key points for extension:
| Attribute / Method | Purpose |
|---|---|
response_type | Set to the target Python type; used by process_response() for conversion |
validate_error_message | Override the message shown on type conversion failure |
illegal_choice_message | Override the message shown on invalid choice |
prompt_suffix | Override the trailing string appended to the prompt (default ": ") |
process_response() | Override to add custom validation; raise InvalidResponse on failure |
render_default() | Override to change how the default value is displayed |
pre_prompt() | Override to print anything before each prompt attempt |
on_validate_error() | Override to customise error handling |
Example: a custom process_response() that enforces a numeric range would call IntPrompt's base implementation then raise InvalidResponse if the value is out of range, as demonstrated in the module's __main__ block rich/prompt.py366-401
Sources: rich/prompt.py30-52 rich/prompt.py227-268
All prompt classes and ask() accept a stream keyword argument of type TextIO. When provided, input is read from this stream rather than the terminal. This is used in tests to simulate user input without interactive terminal access.
Sources: rich/prompt.py111-149 tests/test_prompt.py7-21
The module can be run directly to exercise all prompt types interactively:
python -m rich.prompt
This runs the __main__ block rich/prompt.py366-401 which demonstrates Confirm, IntPrompt, Prompt with password masking, Prompt with choices, and case-insensitive choices.
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.