Skip to main content

A library of extensible and modular CLI prompt elements

Project description

Questo

A library of extensible and modular CLI prompt elements


CI codecov PyPI - Downloads

Overview

Questo provides a set of modular and extensible CLI elements. Unlike other libraries that provide ready-made functions, Questo exposes the internal state and event loop, allowing for complete customization of behavior and rendering.

Element Functionality
Prompt Text input with support for completions and cursor navigation
Select List selection with support for single/multi-select, filtering, and pagination

Installation

From PyPI:

pip install questo

Using Poetry:

poetry add questo

Usage

Questo elements are designed to be used within your own event loop. This gives you full control over how keys are handled and how the element is rendered.

Architecture

Each element in Questo consists of three main components:

  1. State: A dataclass that holds the current state of the element (e.g., current value, cursor position, selected index).
  2. Element: A class that wraps the state and handles the display context.
  3. Key Handler: A function that takes the current state and a keypress, returning a new state.
  4. Renderer: A function that takes the current state and returns a string representation to be shown in terminal.

Example

Here is a complete example showing how to use Prompt and Select elements.

from yakh import get_key
from questo import prompt, select

# --- Prompt Example ---

# 1. Instantiate the element
name_prompt = prompt.Prompt()

# 2. Initialize the state
name_prompt.state = prompt.PromptState(title="What is your name?")

# 3. Run the event loop
with name_prompt.displayed():
    while True:
        # Get keypress
        key = get_key()
        
        # Update state based on keypress
        name_prompt.state = prompt.key_handler(name_prompt.state, key)
        
        # Check for exit or abort conditions
        if name_prompt.state.exit or name_prompt.state.abort:
            break

# 4. Get the result
name = name_prompt.result

if name:
    print(f"Hello, {name}!")

# --- Select Example ---

# 1. Instantiate the element
color_select = select.Select()

# 2. Initialize the state
color_select.state = select.SelectState(
    title="Choose a color:",
    options=["Red", "Green", "Blue", "Yellow", "Magenta", "Cyan"],
    page_size=3,
    pagination=True
)

# 3. Run the event loop
with color_select.displayed():
    while True:
        key = get_key()
        color_select.state = select.key_handler(color_select.state, key)
        if color_select.state.exit or color_select.state.abort:
            break

# 4. Get the result
color_index = color_select.result
if color_index is not None:
    print(f"You chose: {color_select.state.options[color_index]}")

Customization

Because Questo exposes the state and renderer, you can easily customize the appearance and behavior.

Custom Renderer

You can provide a custom renderer function to change how the element looks.

from questo import prompt

def my_custom_renderer(state: prompt.PromptState) -> str:
    return f"[bold green]{state.title}[/bold green]\n> {state.value}"

p = prompt.Prompt(renderer=my_custom_renderer)

Custom Key Handler

You can wrap or replace the default key handler to add custom key bindings.

from questo import prompt
from yakh.key import Keys

def my_key_handler(state, key):
    if key == Keys.TAB:
        state.value = "TAB pressed!"
        return state
    return prompt.key_handler(state, key)

Contributing

To start development you can clone the repository:

git clone https://github.com/petereon/questo.git

Change the directory to the project directory:

cd ./questo/

This project uses poetry as a dependency manager. You can install the dependencies using:

poetry install

For testing, this project relies on pytest.

poetry run poe test

License

The project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

questo-0.4.2.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

questo-0.4.2-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file questo-0.4.2.tar.gz.

File metadata

  • Download URL: questo-0.4.2.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for questo-0.4.2.tar.gz
Algorithm Hash digest
SHA256 bcc917c2f1a65872e2bd02e79e226a716fd2d68a1ebe0d23c1828aa116aa6da6
MD5 b01c6c1f9f27879a2dacc1fd31e91c84
BLAKE2b-256 a8e64a86ccd5710c2fddae92786f15f2c69637b417905ff239d7424b55e342cb

See more details on using hashes here.

File details

Details for the file questo-0.4.2-py3-none-any.whl.

File metadata

  • Download URL: questo-0.4.2-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for questo-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1afce34a638601b54fbd697e99e7551813fafb513fe523165394eb12f9607b43
MD5 45d963fbeee11f9c0b37457cf67cbf58
BLAKE2b-256 049e2669ac7d718539a3783c3a6c440b3440b68193b59d763d7f89d33c0b1e8e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page