Usage

The idea is quite simple:

  1. Create an array of Questions

  2. Call the prompt render.

Each Question require some common arguments. So, you just need to know which kind of Questions and Arguments are available.

Question types

TEXT

Expects a text answer.

EDITOR

Expects a text answer, entered through external editor.

PASSWORD

Do not prompt the answer.

CONFIRM

Requires a boolean answer.

LIST

Show a list and allow to select just one answer.

CHECKBOX

Show a list and allow to select a bunch of them.

PATH

Requires valid path and allows additional validations.

There are pictures of some of them in the Examples section.

Question Arguments

The main object is Question, but it should not be instantiated. You must use any of the subclasses, listed below. All of them have the next attributes that can be set in the initialization:

name

It will be the key in the hash of answers. So, it is mandatory.

You can use any String or hashable code as value.

message

Contains the prompt to be shown to the user, and is mandatory too.

You can use a new style formatted string, using the previous answers, and it will be replaced automatically:

from inquirer3 import Text

questions = [
    Text(name='name', message="What's your name?"),
    Text(name='surname', message="What's your surname, {name}")
]

The value can be a function, with the next sign:

def get_message(answers): return str()

Example:

from inquirer3 import Text

def get_message(answers):
    return "What's your name?"

Text(name='name', message=get_message)

Where answers is the dictionary with previous answers.

If the message is too long for the terminal, it will be cut to fit.

default

Stores the default value to be used as answer. This allows the user just to press Enter to use it. It is optional, using None if there is no input and no default value.

As in message, you can use a new format string or a function with the sign:

def get_default(answers): return str()

Where answers is a dict containing all previous answers.

Remember that it should be a list for Checkbox questions.

choices

Mandatory just for Checkbox and List questions; the rest of them do not use it.

It contains the list of selectable answers.

Its value can be a list of strings, new format style strings or pairs(tuples) or a function that returns that list, with the sign:

def get_choices(answers): return list(str())

If any of the list values is a pair, it should be a tuple like: (label, value). Then the label will be shown but the value will be returned.

As before, the answers is a dict containing the previous answers.

validate

Optional attribute that allows the program to check if the answer is valid or not. It requires a boolean value or a function with the sign:

def validate(answers, current): return boolean()

Where answers is a dict with previous answers again and current is the current answer. If you want to customize the validation message, you can raise your own error with specific reason: inquirer.errors.ValidationError('', reason='your reason that will be displayed to the user') inside the validation function, but be aware that if the validation passes you still have to return True!

Example:

import random
from inquirer3 import errors, Text

def validation_function(answers, current):
    if random.random() > 0.5:
        raise errors.ValidationError('', reason='Sorry, just have bad mood.')

    return True


Text('nothing', "Moody question", validate=validation_function)
Text('age', "How old are you?", validate=lambda _, c: 0 <= c < 120)

ignore

Questions are statically created and some of them may be optional depending on other answers. This attribute allows to control this by hiding the question.

Its value is boolean or a function with the sign:

def ignore(answers): return boolean()

where answers contains the dict of previous answers again.

Example:

import inquirer3

questions = [
    inquirer3.Text("name", message="What's your name?"),
    inquirer3.Text(
        "surname",
        message="What's your surname, {name}?",
        ignore=lambda x: x["name"].lower() == "anonymous"
    ),
    inquirer3.Confirm("married", message="Are you married?"),
    inquirer3.Text(
        "time_married",
        message="How long have you been married?",
        ignore=lambda x: not x["married"]
    )
]

Path Question

Path Question accepts any valid path which can be both absolute or relative. By default, it only validates the validity of the path. Except of validation it returns normalized path, and it expands home alias (~).

The Path Question have additional arguments for validating paths.

path_type

Validation argument that enables to enforce if the path should be aiming to file (Path.FILE) or directory (Path.DIRECTORY).

By default, nothing is enforced (Path.ANY).

from inquirer3 import Path

Path('log_file', 'Where should be log files located?', path_type=Path.DIRECTORY)

exists

Validation argument that enables to enforce if the provided path should or should not exist. Expects True if the path should exist, or False if the path should not exist.

By default, nothing is enforced (None)

from inquirer3 import Path

Path('config_file', 'Point me to your configuration file.', exists=True, path_type=Path.File)

normalize_to_absolute_path

Argument which will enable normalization on the provided path. When enabled, in case of relative path would be provided the Question will normalize it to absolute path.

Expects bool value. Default False.

from inquirer3 import Path

Path('config_file', 'Point me to your configuration file.', normalize_to_absolute_path=True)

Creating the Question object

With this information, it is easy to create a Question object:

from inquirer3 import Text

Text('name', "What's your name?")

It’s possible to load the Question objects from a dict, or even the whole list of them, with the method load_from_dict and load_from_list, respectively.

The method load_from_json has been added as commodity to use JSON inputs instead. Here you have an example:

import os
import sys
from pprint import pprint


sys.path.append(os.path.realpath("."))
import inquirer3  # noqa


with open("examples/test_questions.json") as fd:
    questions = inquirer3.load_from_json(fd.read())

answers = inquirer3.prompt(questions)

pprint(answers)

The prompter

The last step is to call the prompter With the list of Question:

answers = inquirer.prompt(questions)

This line will ask the user for information and will store the answers in a dict, using the question name as key and the user response as value.

Remember the prompt always require a list of Question as input.

Themes

Simply change the colorscheme and some icons passing a theme object defined in inquirer.themes. You can define your own via class, dict or json or you can use on of the pre-defined themes: Default, GreenPassion and BlueComposure. Keep in mind however, that not every console supports all colors and unicode-characters! So test which theme works for you.

{{ inquirer themes compare }}

Here is an example how to use a theme:

import inquirer3
from inquirer3.themes import GreenPassion


q = [
    inquirer3.Text("name", message="Whats your name?", default="No one"),
    inquirer3.List("jon", message="Does Jon Snow know?", choices=["yes", "no"], default="no"),
    inquirer3.Checkbox(
        "kill_list", message="Who you want to kill?", choices=["Cersei", "Littlefinger", "The Mountain"]
    ),
]

inquirer3.prompt(q, theme=GreenPassion())

Result:

{{ inquirer theme }}

Shortcut functions

For one-off prompts, you can use the shortcut functions.

import inquirer3

text = inquirer3.text(message="Enter your username")
password = inquirer3.password(message='Please enter your password'),
choice = inquirer3.list_input("Public or private?",
                              choices=['public', 'private'])
correct = inquirer3.confirm("This will delete all your current labels and "
                        "create a new ones. Continue?", default=False)

Autocompletion

You can optionally provide an autocompletion function to the Text question type and the Checkbox question type’s “Other” option (if enabled).

The autocompletion function is called with the current input string (text) as the first argument and the number of times the user has pressed TAB as the second argument (state). If the user changes their input, state will reset to 0.

This information can be used to provide completion based on what the user has already input, and/or the number of times the user has pressed TAB, allowing you to cycle through multiple possible completions.

The function should return what to replace the entire current input with as a str. Any other types will be ignored.

import inquirer3


suggestions = ["inquirer3", "hello", "world", "foo", "bar", "baz", "qux"]


def autocomplete_fn(_text, state):
    # Every time the user presses TAB, we'll switch to the next suggestion
    # The `state` variable contains the index of the current suggestion
    # We can wrap it around to the first suggestion if we reach the end
    return suggestions[state % len(suggestions)]


questions = [
    inquirer3.Text(
        "name",
        message="Press TAB to cycle through suggestions",
        autocomplete=autocomplete_fn,
    ),
]

answers = inquirer3.prompt(questions)

print(answers)