Questo
A library of extensible and modular CLI prompt elements
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:
- State: A dataclass that holds the current state of the element (e.g., current value, cursor position, selected index).
- Element: A class that wraps the state and handles the display context.
- Key Handler: A function that takes the current state and a keypress, returning a new state.
- 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.
Metadata
Release files for questo 0.4.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| questo-0.4.2.tar.gz | 10.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| questo-0.4.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.9 kB
Release files / questo-0.4.2.tar.gz
| Download URL | questo-0.4.2.tar.gz |
|---|---|
| Size | 10.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bcc917c2f1a65872e2bd02e79e226a716fd2d68a1ebe0d23c1828aa116aa6da6
|
|
BLAKE2b-256 checksum How to use checksums |
a8e64a86ccd5710c2fddae92786f15f2c69637b417905ff239d7424b55e342cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / questo-0.4.2-py3-none-any.whl
| Download URL | questo-0.4.2-py3-none-any.whl |
|---|---|
| Size | 12.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1afce34a638601b54fbd697e99e7551813fafb513fe523165394eb12f9607b43
|
|
BLAKE2b-256 checksum How to use checksums |
049e2669ac7d718539a3783c3a6c440b3440b68193b59d763d7f89d33c0b1e8e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|