Questionary Documentation

repository·master·Indexed 24 days ago

https://github.com/tmbo/questionary

A Python library for building interactive command-line interfaces (CLIs) with pretty user prompts. Version 2.1.0 supports various prompt types including text, password, confirm, select, checkbox, path, and autocomplete. It features input validation via Validator classes or functions, custom styling through the Style class, asynchronous prompt support with ask_async, and the ability to execute sequences of questions using questionary.prompt() or structured data collection with questionary.form().

Tokens
7.8K
Snippets
16
Records
50
Agent score
79%

What's inside questionary

  1. Available Question Types in Questionary

    master

    Questionary provides several question types to handle different user input scenarios. Use the following mapping to choose the right method for your use case:

    • Free text input: questionary.text()
    • Hidden text (passwords): questionary.password()
    • File or directory paths (with autocompletion): questionary.path()
    • Yes/No questions: questionary.confirm()
    • Single item selection (styled list): questionary.select()
    • Single item selection (unformatted list): questionary.rawselect()
    • Multiple item selection: questionary.checkbox()
    • Free text with autocomplete suggestions: questionary.autocomplete()
    • Wait for user input: questionary.press_any_key_to_continue()

    Additionally, you can use questionary.print() to display formatted text to the terminal.

  2. Handle keyboard interrupts (Safe vs Unsafe)

    master

    Questionary provides two ways to handle Ctrl+C (KeyboardInterrupt):

    Safe Mode (Captures Interrupts)

    In safe mode, Questionary catches the interrupt, displays a message (e.g., "Cancelled by user"), and returns None. Safe methods include:

    • questionary.prompt()
    • Form.ask()
    • Question.ask() (returned by functions like text(), checkbox(), etc.)

    Unsafe Mode (Does NOT capture Interrupts)

    In unsafe mode, the interrupt is raised to the caller. You must wrap these calls in a try/except KeyboardInterrupt block. Unsafe methods include:

    • questionary.unsafe_prompt()
    • Form.unsafe_ask()
    • Question.unsafe_ask()
  3. How questionary concepts work

    master

    Questionary operates on two primary mental models:

    1. Single Questions: Individual prompts created via specific type methods (e.g., questionary.text()) that are executed via .ask().
    2. Collections of Questions:
      • Forms: Created via questionary.form(), using keyword arguments to define field names and Question objects. This is a programmatic, object-oriented way to build flows.
      • Prompts: Created via questionary.prompt(), using a list of configuration dictionaries. This is a data-driven way to define flows, where each dictionary specifies a type, name, and message.
  4. Quickstart with Questionary prompts

    master

    Questionary provides several prompt types to collect user input. Most prompts are invoked by calling the prompt method and then calling .ask() to retrieve the user's response.

    Supported prompt types include:

    • text(): Standard text input.
    • password(): Masked text input for sensitive data.
    • confirm(): Boolean confirmation (Yes/No).
    • select(): Single-choice selection from a list.
    • rawselect(): Single-choice selection using raw input.
    • checkbox(): Multiple-choice selection from a list.
    • path(): File path input.
    • autocomplete(): Text input with suggestions.

    Example usage:

    import questionary
    
    questionary.text("What's your first name").ask()
    questionary.password("What's your secret?").ask()
    questionary.confirm("Are you amazed?").ask()
    
    questionary.select(
        "What do you want to do?",
        choices=["Order a pizza", "Make a reservation", "Ask for opening hours"],
    ).ask()
    
    questionary.rawselect(
        "What do you want to do?",
        choices=["Order a pizza", "Make a reservation", "Ask for opening hours"],
    ).ask()
    
    questionary.checkbox("Select toppings", choices=["foo", "bar", "bazz"])
    questionary.path("Path to the projects version file").ask()
    import questionary
    
    questionary.text("What's your first name").ask()
    questionary.password("What's your secret?").ask()
    questionary.confirm("Are you amazed?").ask()
    
    questionary.select(
        "What do you want to do?",
        choices=["Order a pizza", "Make a reservation", "Ask for opening hours"],
    ).ask()
    
    questionary.rawselect(
        "What do you want to do?",
        choices=["Order a pizza", "Make a reservation", "Ask for opening hours"],
    ).ask()
    
    questionary.checkbox("Select toppings", choices=["foo", "bar", "bazz"]
    ).ask()
    
    questionary.path("Path to the projects version file").ask()
  5. Set up a development environment for Questionary

    master

    To contribute to Questionary, follow these steps to configure your local environment:

    1. Fork the repository on GitHub.
    2. Install Poetry.
    3. Run make develop to configure the development environment.
    4. Write tests for your changes.
    5. Run quality checks using the following commands:
      • Linting: make lint
      • Unit tests: make test
      • Type checks: make types
    6. Submit a pull request.
    make develop
    $ make lint
    $ make test
    $ make types
  6. Ask multiple questions using a form

    master

    Use questionary.form() to ask a collection of questions sequentially. You pass the questions as keyword arguments where the key is the name of the field and the value is a Question instance. The .ask() method returns a dictionary containing the answers, mapped to the keys provided in the form.

    import questionary
    
    answers = questionary.form(
        first = questionary.confirm("Would you like the next question?", default=True),
        second = questionary.select("Select item", choices=["item1", "item2", "item3"])
    ).ask()
    
    print(answers)
    # Output format: {'first': True, 'second': 'item2'}
  7. Customize prompt themes and styling

    master

    You can define a custom Style using a list of tuples mapping identifiers to terminal styling strings (e.g., 'fg:#673ab7 bold'). Pass this style to the question via the style parameter.

    Available Style Identifiers:

    • qmark: Token in front of the question
    • question: Question text
    • answer: Submitted answer text
    • pointer: Pointer used in select and checkbox prompts
    • highlighted: Pointed-at choice in select and checkbox prompts
    • selected: Style for a selected item in a checkbox
    • separator: Separator in lists
    • instruction: User instructions for select, rawselect, checkbox
    • text: Plain text
    • disabled: Disabled choices for select and checkbox
    from questionary import Style
    
    custom_style_fancy = Style([
        ('qmark', 'fg:#673ab7 bold'),
        ('question', 'bold'),
        ('answer', 'fg:#f44336 bold'),
        ('pointer', 'fg:#673ab7 bold'),
        ('highlighted', 'fg:#673ab7 bold'),
        ('selected', 'fg:#cc5454'),
        ('separator', 'fg:#cc5454'),
        ('instruction', ''),
        ('text', ''),
        ('disabled', 'fg:#858585 italic')
    ])
    
    questionary.text("What's your phone number", style=custom_style_fancy).ask()
  8. Ask multiple questions using a dictionary list with prompt()

    master

    The questionary.prompt() function allows you to ask a collection of questions by passing a list of dictionaries. Each dictionary defines the question's configuration. This is an alternative to questionary.form() when you prefer a data-driven approach rather than using Question instances. The returned answers are a dictionary mapping the name key from each dictionary to the user's response.

    import questionary
    
    questions = [
      {
        "type": "confirm",
        "name": "first",
        "message": "Would you like the next question?",
        "default": True,
      },
      {
        "type": "select",
        "name": "second",
        "message": "Select item",
        "choices": ["item1", "item2", "item3"],
      },
    ]
    
    answers = questionary.prompt(questions)
    print(answers)
    # Output format: {'first': True, 'second': 'item2'}
  9. How to create a new release

    master

    To release a new version of Questionary, perform the following steps:

    1. Update the version number in both questionary/version.py and pyproject.toml.
    2. Add a new section for the release in the changelog.
    3. Commit the changes.
    4. Tag the commit with the release version number using git tag.

    Note: GitHub Actions will automatically build and push the updated library to PyPI once the release is processed.

  10. Create a command line recording (GIF)

    master

    To create a GIF recording of a command line interaction, use asciinema and asciicast2gif.

    1. Install the required tools:
      • macOS: brew install asciinema
      • Global npm: npm install --global asciicast2gif
    2. Start recording with asciinema rec.
    3. Perform the actions you wish to record.
    4. Convert the recording to a GIF using asciicast2gif with the following command structure: asciicast2gif -h <height> -w <width> -s <speed> <recording_file> <output_file>
    $ brew install asciinema
    $ npm install --global asciicast2gif
    $ asciinema rec
    $ asciicast2gif -h 7 -w 120 -s 2 <recording> output.gif