41

I'd like to create a Python CLI with an item selection interface that allows users to choose an item from a list. Something like:

Select a fruit (up/down to select and enter to confirm):
[x] Apple
[ ] Banana
[ ] Orange

I'd like users to be able to change their selection using the up/down arrows and press Enter to confirm.

Does a Python module exist with this functionality? I tried searching but couldn't find exactly what I wanted.

The select-shell Node.js package does exactly what I want.

The pick Python module does what I want, but it uses curses and opens up a simple GUI. I would like to avoid creating a GUI and keep all output in the terminal: this likely requires updating lines displayed to the terminal.

I'm currently using click but I don't believe it supports this functionality. I'm not sure how exactly to implement this kind of feature using cmd/readline and would appreciate any insight.

Dan Zheng
  • 1,493
  • 2
  • 13
  • 22

4 Answers4

57

After a bit of searching, I found two libraries that met my needs!

The first is python-inquirer, a Python port of Inquirer.js, a CLI library used by projects like Yeoman. I found this library to have a really nice API (built on top of blessings) but lacks polish when it comes to design/features.

The second (which I will be using) is whaaaaat, another Python port of Inquirer. This library offers functionality much closer to the original Inquirer.js and is exactly what I needed. The API is less clean than that of python-inquirer, however.

Examples:

python-inquirer example:

from pprint import pprint
import inquirer

questions = [
    inquirer.List(
        "size",
        message="What size do you need?",
        choices=["Jumbo", "Large", "Standard", "Medium", "Small", "Micro"],
    ),
]

answers = inquirer.prompt(questions)
pprint(answers)

whaaaaat example:

from whaaaaat import prompt, print_json, Separator

questions = [
    {
        "type": "list",
        "name": "theme",
        "message": "What do you want to do?",
        "choices": [
            "Order a pizza",
            "Make a reservation",
            Separator(),
            "Ask for opening hours",
            {"name": "Contact support", "disabled": "Unavailable at this time"},
            "Talk to the receptionist",
        ],
    },
    {
        "type": "list",
        "name": "size",
        "message": "What size do you need?",
        "choices": ["Jumbo", "Large", "Standard", "Medium", "Small", "Micro"],
        "filter": lambda val: val.lower(),
    },
]

answers = prompt(questions)
print_json(answers)
Dan Zheng
  • 1,493
  • 2
  • 13
  • 22
  • 6
    Notes: (1) Windows support on python-inquirer is experimental (2) Whaaaat is stale, with the developer stating in the readme that he does not have the time to work on the project. – miwe Sep 03 '20 at 19:21
  • I think python-inquirer is also using curses? – wong2 Dec 07 '21 at 03:16
8

For simple choices you can use the simple-term-menu package. It is simple, small and has no dependencies to other packages.

Example:

from simple_term_menu import TerminalMenu

terminal_menu = TerminalMenu(["entry 1", "entry 2", "entry 3"])
choice_index = terminal_menu.show()

simple-term-menu

IngoMeyer
  • 303
  • 4
  • 7
  • 10
    Attention: simple_term_menu does not work on windows. See https://github.com/IngoMeyer441/simple-term-menu#overview – miwe Sep 03 '20 at 19:09
5

Few more alternatives for command-line form input libraries:

Note: I am the maintainer of beaupy

LordBertson
  • 398
  • 4
  • 11
  • 2
    +1 for making me go from "it's gonna be a hasle to find a Windows compatible option" to "oh..which one should I choose?" – Paiusco Jul 27 '23 at 09:07
0

You mention the click package, and mention that you are not sure how to implement this feature. It seems like choice-options are the intended way to implement single choice questions.

The generated output will not be nearly as nice as in some of the other packages mentioned in the other answers. However, click is well maintained, active, and works on both UNIX and WIN - critical arguments if you are planning to release a library.

miwe
  • 543
  • 3
  • 16
  • 1
    The single choice might be a deal breaker for the OP, it's a fairly distinct user experience to an interactive multiple choice interface. – verwirrt Jul 14 '23 at 21:34
  • True: I'm not too familiar with choice-options, but yeah, it looks as if multiple-choice was not supported. However, I understood the OPs question ("Select a fruit") as explicitely targeting single-choice... – miwe Jul 16 '23 at 20:09