CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-questionary

Python library to build pretty command line user prompts with interactive forms and validation

Overall
score

96%

Overview
Eval results
Files

selection-prompts.mddocs/

Selection Prompts

Selection prompts enable users to choose from predefined options using single-choice selection, multi-choice checkboxes, or keyboard shortcut-based selection.

Capabilities

Single Selection

Interactive single-choice selection from a list of options with arrow key navigation, search filtering, and keyboard shortcuts.

def select(message: str, choices: Sequence[Union[str, Choice, Dict]], 
           default: Optional[Union[str, Choice, Dict]] = None, qmark: str = "?", 
           pointer: Optional[str] = "»", style: Optional[Style] = None, 
           use_shortcuts: bool = False, use_arrow_keys: bool = True, 
           use_indicator: bool = False, use_jk_keys: bool = True, 
           use_emacs_keys: bool = True, use_search_filter: bool = False, 
           show_selected: bool = False, show_description: bool = True, 
           instruction: Optional[str] = None, **kwargs) -> Question:
    """
    Create a single-choice selection prompt.
    
    Args:
        message: The question/prompt text to display
        choices: List of options (strings, Choice objects, or dicts)
        default: Default selected choice
        qmark: Question prefix symbol (default "?")
        pointer: Selection pointer symbol (default "»")
        style: Custom styling configuration
        use_shortcuts: Enable keyboard shortcuts for choices
        use_arrow_keys: Enable up/down arrow navigation
        use_indicator: Show selection indicator next to choices
        use_jk_keys: Enable j/k vim-style navigation
        use_emacs_keys: Enable Emacs-style key bindings
        use_search_filter: Enable search/filter functionality
        show_selected: Display selected choice after selection
        show_description: Show choice descriptions if available
        instruction: Additional instruction text
        **kwargs: Additional prompt_toolkit arguments
    
    Returns:
        Question instance ready for execution
    """

Multiple Selection (Checkbox)

Multi-choice selection prompt allowing users to select multiple options with checkbox-style indicators.

def checkbox(message: str, choices: Sequence[Union[str, Choice, Dict]], 
             default: Optional[str] = None, 
             validate: Callable[[List[str]], Union[bool, str]] = lambda a: True,
             qmark: str = "?", pointer: Optional[str] = "»", 
             style: Optional[Style] = None, 
             initial_choice: Optional[Union[str, Choice, Dict]] = None, 
             use_arrow_keys: bool = True, use_jk_keys: bool = True, 
             use_emacs_keys: bool = True, use_search_filter: bool = False, 
             instruction: Optional[str] = None, show_description: bool = True, 
             cycle_list: bool = True, **kwargs) -> Question:
    """
    Create a multiple-choice checkbox prompt.
    
    Args:
        message: The question/prompt text to display
        choices: List of options (strings, Choice objects, or dicts)
        default: Default selected choice name
        validate: Validation function for selected choices
        qmark: Question prefix symbol (default "?")
        pointer: Selection pointer symbol (default "»")
        style: Custom styling configuration
        initial_choice: Initially focused choice
        use_arrow_keys: Enable up/down arrow navigation
        use_jk_keys: Enable j/k vim-style navigation
        use_emacs_keys: Enable Emacs-style key bindings
        use_search_filter: Enable search/filter functionality
        instruction: Additional instruction text
        show_description: Show choice descriptions if available
        cycle_list: Allow cycling through list boundaries
        **kwargs: Additional prompt_toolkit arguments
    
    Returns:
        Question instance ready for execution
    """

Raw Selection (Keyboard Shortcuts)

Single-choice selection using only keyboard shortcuts without arrow key navigation.

def rawselect(message: str, choices: Sequence[Union[str, Choice, Dict]], 
              default: Optional[str] = None, qmark: str = "?", 
              pointer: Optional[str] = "»", style: Optional[Style] = None, 
              **kwargs) -> Question:
    """
    Create a keyboard shortcut-based selection prompt.
    
    Args:
        message: The question/prompt text to display
        choices: List of options (strings, Choice objects, or dicts)
        default: Default selected choice
        qmark: Question prefix symbol (default "?")
        pointer: Selection pointer symbol (default "»")
        style: Custom styling configuration
        **kwargs: Additional prompt_toolkit arguments
    
    Returns:
        Question instance ready for execution
    """

Choice Configuration

Choice Objects

Advanced choice configuration with custom values, descriptions, and states.

class Choice:
    def __init__(self, title: FormattedText, value: Optional[Any] = None, 
                 disabled: Optional[str] = None, checked: Optional[bool] = False,
                 shortcut_key: Optional[Union[str, bool]] = True, 
                 description: Optional[str] = None) -> None:
        """
        Configure a choice for selection prompts.
        
        Args:
            title: Display text for the choice
            value: Return value when choice is selected (defaults to title)
            disabled: Reason text if choice is disabled (None = enabled)
            checked: Initially selected state for checkbox prompts
            shortcut_key: Keyboard shortcut (True = auto-generate, False = none)
            description: Additional description text
        """

    @staticmethod
    def build(c: Union[str, Choice, Dict]) -> Choice:
        """
        Build Choice from string, existing Choice, or dictionary.
        
        Args:
            c: Choice specification
            
        Returns:
            Choice instance
        """

Separator Objects

Visual separators for organizing choice lists.

class Separator(Choice):
    def __init__(self, line: Optional[str] = None) -> None:
        """
        Create a visual separator for choice lists.
        
        Args:
            line: Custom separator text (default: 15 dashes)
        """

Usage Examples

Basic Selection

import questionary

# Simple string choices
color = questionary.select(
    "Choose a color:",
    choices=["Red", "Green", "Blue"]
).ask()

# With default selection
size = questionary.select(
    "Choose size:",
    choices=["Small", "Medium", "Large"],
    default="Medium"
).ask()

Advanced Choice Configuration

import questionary
from questionary import Choice, Separator

# Using Choice objects with custom values
action = questionary.select(
    "What would you like to do?",
    choices=[
        Choice("Create new project", value="create"),
        Choice("Open existing project", value="open"),
        Choice("Delete project", value="delete", disabled="Not implemented"),
        Separator(),
        Choice("Exit", value="exit")
    ]
).ask()

# Choices with descriptions
framework = questionary.select(
    "Choose framework:",
    choices=[
        Choice("Django", description="Full-featured web framework"),
        Choice("Flask", description="Lightweight WSGI framework"),
        Choice("FastAPI", description="Modern async web framework")
    ],
    show_description=True
).ask()

Checkbox (Multiple Selection)

import questionary

# Basic checkbox selection
toppings = questionary.checkbox(
    "Select pizza toppings:",
    choices=["Cheese", "Pepperoni", "Mushrooms", "Olives", "Peppers"]
).ask()

# With validation requiring at least one selection
def validate_selection(answers):
    if len(answers) == 0:
        return "Please select at least one option"
    return True

services = questionary.checkbox(
    "Which services to enable?",
    choices=["Database", "Cache", "Queue", "Storage"],
    validate=validate_selection
).ask()

# Pre-checked options
features = questionary.checkbox(
    "Select features:",
    choices=[
        Choice("Authentication", checked=True),
        Choice("API Documentation", checked=True),
        Choice("Admin Panel", checked=False),
        Choice("Email Service", checked=False)
    ]
).ask()

Raw Selection with Shortcuts

import questionary

# Automatic shortcut generation
priority = questionary.rawselect(
    "Select priority:",
    choices=["High", "Medium", "Low"]
).ask()

# Custom shortcuts
environment = questionary.rawselect(
    "Deploy to:",
    choices=[
        Choice("Development", shortcut_key="d"),
        Choice("Staging", shortcut_key="s"),
        Choice("Production", shortcut_key="p")
    ]
).ask()

Search and Filtering

import questionary

# Enable search functionality
country = questionary.select(
    "Select country:",
    choices=["United States", "Canada", "United Kingdom", "Germany", "France", "Japan"],
    use_search_filter=True,
    instruction="Type to filter options"
).ask()

Keyboard Navigation Options

import questionary

# Customize navigation keys
option = questionary.select(
    "Choose option:",
    choices=["Option 1", "Option 2", "Option 3"],
    use_arrow_keys=True,    # Up/down arrows
    use_jk_keys=True,       # j/k vim-style
    use_emacs_keys=True,    # Emacs bindings
    use_shortcuts=True      # Number shortcuts
).ask()

Install with Tessl CLI

npx tessl i tessl/pypi-questionary

docs

autocomplete-paths.md

core-classes.md

execution-control.md

forms.md

index.md

selection-prompts.md

text-input.md

tile.json