Console Module
Provides comprehensive tools for terminal output and user interaction.
Includes styled logging, box rendering, progress bars, throbbers,
interactive prompts, key reading, and command-line argument parsing.
FRAMES_STANDARD
FRAMES_STANDARD: Final[tuple[str, ...]] = ("⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏")Throbber frames preset: A standard, clean, and modern Braille circular spinner.
FRAMES_WINDMILL
FRAMES_WINDMILL: Final[tuple[str, ...]] = ("⠓⠆", "⠳⠄", "⠹⠄", "⠽ ", "⠼⠁", "⠞⠁", "⠖⠃", "⠓⠃", "⠓⠆", "⠙⠆", "⠹⠄", "⠸⠅", "⠼⠁", "⠴⠃", "⠖⠃", "⠖⠆")Throbber frames preset: A wide, dual-character Braille windmill animation.
.is_arg
is_arg: bool.opts
opts: frozenset[str] | None.nargs
nargs: int | Literal["?", "*", "+"].expects_value
expects_value: str | None.optional_value
optional_value: bool.choices
choices: Iterable[str] | None.required
required: bool.help
help: TextRenderable | NoneParsedArgData
class ParsedArgData(
self,
exists: bool = False,
values: tuple[str, ...] = ,
is_arg: bool = False,
opt: str | None = None,
)Represents the result of a parsed command-line argument or option.
exists– Whether the argument or option was found in the command-line input or not.is_arg– Whether the value was provided as a positional argument.values– The tuple of values associated with the argument or option.opt– The specific option that was found (e.g.,-v,-vv,-vvv), orNonefor arguments.
When the ParsedArgData instance is accessed as a boolean
it will correspond to the exists attribute.
.val()
def val(
self,
cast_type: Callable[[str], Any] | type[Any] = str,
default: Any = None,
) -> AnyGet the parsed value, optionally casting it to a specified type and providing a fallback default.
cast_type– The type to cast to (e.g.,int,Path, …).default– The fallback value ifexistsis false or if no values exist.
Raises a ValueError if the value cannot be cast to the specified type.
.vals()
def vals(
self,
cast_type: Callable[[str], Any] | type[Any] = str,
default: Any = (),
) -> AnyGet all parsed values, optionally casting them to a specified type and providing a fallback default.
cast_type– The type to cast to (e.g.,int,Path, …).default– The fallback value ifexistsis false or if no values exist.
Raises a ValueError if any value cannot be cast to the specified type.
ArgumentParser
class ArgumentParser(
self,
*,
title: str | None = None,
subtitle: str | None = None,
notice: TextRenderable | object | None = None,
usage: TextRenderable | str | None = None,
controls: Sequence[tuple[str | SeqOrSet[str], TextRenderable]] | None = None,
examples: Sequence[tuple[str, TextRenderable]] | None = None,
epilog: TextRenderable | object | None = None,
prefix_chars: str = "-",
opt_value_sep: str | None = "=",
intermixed: bool = True,
help_opts: SeqOrSet[str] = frozenset({"-h", "--help"}),
)An advanced command-line argument parser with built-in help generation and validation.
title– An optional title for the help print (e.g.,"CLI Tool").subtitle– An optional subtitle (e.g.,"A simple command-line utility").notice– Optional notice or warning text to display right after the title.usage– An optional explicit usage string, containing placeholders:{cmd}– The command name (e.g.,cli-tool).{args}– The arguments placeholder (<input> [output...]).{opts}– The options placeholder ([options]).
controls– A sequence of tuples(control_key, help), wherecontrol_keycan be a single key string or an iterable of strings (e.g.,("WASD", "⏶⏴⏷⏵")).examples– A list of tuples(example_command, comment).epilog– Optional footer text to append to the help print.accent_color– Optional accent color for the help print (e.g.,S.BR.MAGENTA).prefix_chars– Characters that prefix options (default:"-").opt_value_sep– String separating option from value (default:"=").intermixed– Whether options and positional arguments can be intermixed (default:True).help_opts– A set of options that trigger the help print (default:{"-h", "--help"}).
Example Usage
from xulbux import ArgumentParser
parser = ArgumentParser(
title="File Processor",
subtitle="Process files with configurable output",
)
# Define positional arguments:
parser.add_arg("files", nargs="+", help="Input files to process.")
# Define flagged options:
parser.add_opt(("-o", "--output"), expects_value="PATH", help="Output directory.")
parser.add_opt(("-p", "--port"), expects_value="NUM?", help="Optional custom target port.")
parser.add_opt(("-v", "-vv", "-vvv"), "verbosity", help="Set verbosity level.")
args = parser.parse()
# Access parsed arguments:
input_files = args.files.vals()
output_dir = args.output.val(default="./dist")
port = args.port.val(int, default=8080)
verbosity = args.verbosity.opt # -v, -vv, -vvv, or None if not provided.add_arg()
def add_arg(
self,
name: str,
/,
*,
nargs: int | Literal["?", "*", "+"] = 1,
choices: Iterable[str] | None = None,
required: bool | None = None,
help: TextRenderable | None = None,
) -> NoneDefine a new positional argument to parse.
name– The argument name (e.g.,"input_file").nargs– Arguments value count: integer ≥ 1,"?"(0 or 1),"*"(≥ 0), or"+"(≥ 1).choices– Optional iterable of allowed strings for this argument's value.required– Whether the argument must be provided (auto-deduced fromnargsif omitted).help– Help text describing the argument.
.add_opt()
def add_opt(
self,
opts: SeqOrSet[str],
alias: str | None = None,
/,
*,
expects_value: str | Literal[False] = False,
choices: Iterable[str] | None = None,
required: bool = False,
help: TextRenderable | None = None,
) -> NoneDefine a new flagged option to parse.
opts– A collection of option strings (e.g.,{"-f", "--file"}).alias– Optional explicit attribute name onParsedArgs(auto-deduced if omitted).expects_value–Falsefor a boolean option, or a string placeholder (e.g.,"PATH").
Append?(e.g.,"PATH?"or"VAL?") to make the expected value optional.choices– Optional iterable of allowed strings for this option's value.required– Whether the option must be provided.help– Help text describing the option.
.parse()
def parse(
self,
*,
skip: int = 0,
opt_value_sep: str | object | None = _OPT_SEP_DEFAULT,
allow_space_value: bool = True,
intermixed: bool | None = None,
) -> ParsedArgsParse sys.argv and return the strongly-typed ParsedArgs object.
skip– Number of arguments to skip at the start.opt_value_sep– String separating option from value (e.g.,"="for--foo=bar).
Defaults toself.opt_value_sepif omitted. Set toNoneto disable.allow_space_value– Whether to allow space-separated values for options (e.g.,--foo bar).intermixed– Whether options and positional arguments can be intermixed (defaults toself.intermixedif not specified).
Returns the ParsedArgs container.
get_size()
def get_size() -> tuple[int, int]A tuple with the terminal width and height in characters and lines.
get_encoding()
def get_encoding() -> strThe encoding used by the terminal (e.g., utf-8, cp1252, …).
has_color_support()
def has_color_support() -> boolWhether the terminal supports ANSI color codes or not.
pause_exit()
def pause_exit(
prompt: TextRenderable | object = "",
/,
*,
pause: bool = True,
exit_code: int | None = None,
) -> NoneWill print the prompt and then pause and/or exit the program based on the given options.
prompt– The message to print before pausing/exiting (any object, or aSobject).pause– Whether to pause and wait for a key press after printing the prompt.exit_code– The exit code to use when exiting the program, orNoneto not exit.
clear()
def clear() -> NoneClear the terminal screen and scrollback buffer, and reset ANSI formatting.
log()
def log(
title: str | None = None,
prompt: TextRenderable | object = "",
/,
*,
start: str = "",
end: str = "\n",
title_bg_color: BgColorStyle | None = None,
default_color: FgColorStyle | None = None,
tab_size: int = 8,
title_px: int = 1,
title_mx: int = 2,
) -> NonePrints a nicely formatted log message.
title– The title of the log message (e.g.,DEBUG,WARN,FAIL, …).prompt– The log message.start– Something to print before the log is printed.end– Something to print after the log is printed (e.g.,\n).title_bg_color– The background color of thetitle(anSbackground color style).default_color– The default text color of theprompt(anSforeground style).tab_size– The tab size used for the log (default is 8 – matches terminal tabs).title_px– The horizontal padding (in chars) to the title (iftitle_bg_coloris set).title_mx– The horizontal margin (in chars) to the title.
debug()
def debug(
prompt: TextRenderable | object = "Point in program reached.",
/,
*,
active: bool = True,
start: str = "",
end: str = "\n",
default_color: FgColorStyle | None = None,
pause: bool = False,
exit_code: int | None = None,
) -> NoneA preset for log(): DEBUG log message.
prompt– The log message.active– Whether to execute the debug log, pause, and exit or not.start– Something to print before the log is printed.end– Something to print after the log is printed (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).pause– Whether to pause and wait for a key press after printing the log.exit_code– The exit code to use when exiting the program, orNoneto not exit.
info()
def info(
prompt: TextRenderable | object = "Program point reached.",
/,
*,
start: str = "",
end: str = "\n",
default_color: FgColorStyle | None = None,
pause: bool = False,
exit_code: int | None = None,
) -> NoneA preset for log(): INFO log message.
prompt– The log message.start– Something to print before the log is printed.end– Something to print after the log is printed (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).pause– Whether to pause and wait for a key press after printing the log.exit_code– The exit code to use when exiting the program, orNoneto not exit.
done()
def done(
prompt: TextRenderable | object = "Operation completed successfully.",
/,
*,
start: str = "",
end: str = "\n",
default_color: FgColorStyle | None = None,
pause: bool = False,
exit_code: int | None = None,
) -> NoneA preset for log(): DONE log message.
prompt– The log message.start– Something to print before the log is printed.end– Something to print after the log is printed (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).pause– Whether to pause and wait for a key press after printing the log.exit_code– The exit code to use when exiting the program, orNoneto not exit.
warn()
def warn(
prompt: TextRenderable | object = "Warning, unexpected behavior.",
/,
*,
start: str = "",
end: str = "\n",
default_color: FgColorStyle | None = None,
pause: bool = False,
exit_code: int | None = None,
) -> NoneA preset for log(): WARN log message.
prompt– The log message.start– Something to print before the log is printed.end– Something to print after the log is printed (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).pause– Whether to pause and wait for a key press after printing the log.exit_code– The exit code to use when exiting the program, orNoneto not exit.
fail()
def fail(
prompt: TextRenderable | object = "Operation failed, an error occurred.",
/,
*,
start: str = "",
end: str = "\n",
default_color: FgColorStyle | None = None,
pause: bool = False,
exit_code: int | None = None,
) -> NoneA preset for log(): FAIL log message.
prompt– The log message.start– Something to print before the log is printed.end– Something to print after the log is printed (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).pause– Whether to pause and wait for a key press after printing the log.exit_code– The exit code to use when exiting the program, orNoneto not exit.
exit()
def exit(
prompt: TextRenderable | object = "Program ended.",
/,
*,
start: str = "",
end: str = "\n",
default_color: FgColorStyle | None = None,
pause: bool = False,
exit_code: int = 0,
) -> NoReturnA preset for log(): EXIT log message.
prompt– The log message.start– Something to print before the log is printed.end– Something to print after the log is printed (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).pause– Whether to pause and wait for a key press after printing the log.exit_code– The exit code to use when exiting the program.
box()
def box(
*lines: TextRenderable | object,
border: Literal["standard", "rounded", "strong", "double"] | None = "rounded",
border_style: AnyStyle | None = None,
bg: BgColorStyle | bool | None = None,
default_color: FgColorStyle | None = None,
width: int | Literal["full"] | None = None,
align: Literal["left", "center", "right"] = "left",
indent: int = 0,
border_chars: str | None = None,
start: str = "",
end: str = "\n",
print: bool = True,
) -> S | NoneWill format and print or return a styled box with either a border or a background fill.
*lines– The box content (one object per line).
By adding{hr}in the*lines, you can insert horizontal rules to split the box content.border– The border type ("rounded","standard","strong","double"), orNoneto disable borders.border_style– The style of the border (anSnon-background style).bg– Background fill:Nonefor transparent,Truefor default console background, or anSbackground color style (e.g.,S.BG.GREEN,S.BG.hex("#222")).default_color– The default text color of the*lines(anSforeground style).width– The fixed outer box width (in chars),"full"for full terminal width, orNoneto shrinkwrap up to the terminal width.align– The content alignment ("left","center","right").indent– The indentation of the box (in chars).border_chars– Define your own 11-character border set (overwritesborder).start– Something to print/prepend before the box (e.g.,\n).end– Something to print after the box (e.g.,\n).print– Whether to print the box to stdout (True), or return theSobject (False).
The border can be one of the following:
"standard"="┌─┐│┘─└│├─┤""rounded"="╭─╮│╯─╰│├─┤""strong"="┏━┓┃┛━┗┃┣━┫""double"="╔═╗║╝═╚║╠═╣"
Example Usage
Bordered box:
import xulbux as xx
from xulbux import S
xx.console.box(
S.BOLD("A Title"),
"{hr}",
"Some content.",
"Some more content.",
border_style=S.DIM,
)╭────────────────────╮
│ A Title │
├────────────────────┤
│ Some content. │
│ Some more content. │
╰────────────────────╯Filled box with background color:
import xulbux as xx
from xulbux import S
xx.console.box(
S.BOLD("Build Success"),
"Compiled 14 modules without errors.",
bg=S.BG.GREEN,
)
Build Success
Compiled 14 modules without errors.
confirm()
def confirm(
prompt: TextRenderable | object = "Do you want to continue?",
/,
*,
start: S | str = "",
end: S | str = "",
default_color: FgColorStyle | None = None,
default_is_yes: bool = True,
) -> boolAsk a yes/no question.
prompt– The input prompt.start– Something to print before the input.end– Something to print after the input (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).default_is_yes– The default answer if the user just presses enter.
Example Usage
import xulbux as xx
from xulbux import S
if xx.console.confirm("Do you want to overwrite the existing file?", default_is_yes=False):
print("Overwriting file...")multiline_input()
def multiline_input(
prompt: TextRenderable | object = "",
/,
*,
start: str = "",
end: str = "\n",
default_color: FgColorStyle | None = None,
show_keybindings: bool = True,
input_prefix: str = " ⮡ ",
reset_ansi: bool = True,
) -> strAn input where users can write (and paste) text over multiple lines.
prompt– The input prompt.start– Something to print before the input.end– Something to print after the input (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).show_keybindings– Whether to show the special keybindings or not.input_prefix– The prefix of the input line.reset_ansi– Whether to reset the ANSI codes after the user confirms the input.
Example Usage
input()
def input(
prompt: TextRenderable | object = "",
/,
*,
start: str = "",
end: str = "",
default_color: FgColorStyle | None = None,
placeholder: str | None = None,
mask_char: str | None = None,
min_len: int | None = None,
max_len: int | None = None,
allowed_chars: str | AllTextChars = CHARS.ALL,
allow_paste: bool = True,
validator: Callable[[str], str | None] | None = None,
default_val: Any = None,
output_type: type[Any] = str,
) -> AnyActs like a standard Python input() a bunch of cool extra features.
prompt– The input prompt.start– Something to print before the input.end– Something to print after the input (e.g.,\n).default_color– The default text color of theprompt(anSforeground style).placeholder– A placeholder text that is shown when the input is empty.mask_char– If set, the input will be masked with this character.min_len– The minimum length of the input (required to submit).max_len– The maximum length of the input (can't write further if reached).allowed_chars– A string of characters that are allowed to be inputted (default allows all characters).allow_paste– Whether to allow pasting text into the input or not.validator– A function that takes the input string and returns a string error message if invalid, or nothing if valid.default_val– The default value to return if the input is empty.output_type– The type (class) to convert the input to before returning it.
Example Usage
Using a custom validator function:
import xulbux as xx
def email_validator(user_input: str) -> Optional[str]:
if not re.match(r"[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}", user_input):
return "Enter a valid E-Mail address (example@domain.com)"
user_input = xx.console.input(
prompt="E-Mail: ",
placeholder="example@domain.com",
validator=email_validator,
)raw_mode()
def raw_mode() -> Generator[None, None, None]Put the terminal into unbuffered raw mode with echo disabled and enhanced key protocols.
Attention:
This context manager operates exclusively within an active terminal/console environment.
It cannot capture global desktop hotkeys or background input outside the terminal window.
Example Usage
read_key()
def read_key(*, raw: bool = True) -> strRead a single keypress or ANSI/CSI escape sequence from standard input in the terminal.
raw– Whether to automatically enter raw terminal mode to capture unbuffered key presses.
Raises KeyboardInterrupt if Ctrl+C is detected.
Attention:
This function operates exclusively within an active terminal/console environment.
It reads standard input in raw mode and cannot capture global desktop keystrokes
or background input outside the terminal window.
Example Usage
ProgressBar
class ProgressBar(
self,
*,
min_width: int = 10,
max_width: int = 25,
format: Sequence[TextRenderable] | TextRenderable = _DEFAULT_BAR_FORMAT,
limited_format: Sequence[TextRenderable] | TextRenderable = _DEFAULT_LIMITED_BAR_FORMAT,
sep: str = " ",
chars: tuple[str, ...] = ("█", "▉", "▊", "▋", "▌", "▍", "▎", "▏", " "),
)A terminal progress bar with smooth transitions and customizable appearance.
min_width– The min width of the progress bar in chars.max_width– The max width of the progress bar in chars.format– The format strings used to render the progress bar, containing placeholders:{label}{l}{bar}{b}{current}{c}(optional:{char}format specifier for thousands separator, e.g.,{c:,}){total}{t}(optional:{char}format specifier for thousands separator, e.g.,{t:,}){percentage}{percent}{p}(optional:.<num>fformat specifier to round to specified number of decimal places, e.g.,{p:.1f})
limited_format– A simplified format string used when the terminal width is too small for the normalformat.chars– A tuple of characters ordered from full to empty progress:
The first character represents completely filled sections.
Intermediate characters create smooth transitions.
The last character represents empty sections.
The formats can additionally be styled by embedding ANSI from the operator-based API.
For more detailed information, see the ansi module documentation.
Example Usage
.set_width()
def set_width(self, min_width: int | None = None, max_width: int | None = None) -> NoneSet the width of the progress bar.
min_width– The min width of the progress bar in chars.max_width– The max width of the progress bar in chars.
.set_format()
def set_format(
self,
format: Sequence[TextRenderable] | TextRenderable | None = None,
limited_format: Sequence[TextRenderable] | TextRenderable | None = None,
*,
sep: str | None = None,
) -> NoneSet the format string used to render the progress bar.
format– The format strings used to render the progress bar, containing placeholders:{label}{l}{bar}{b}{current}{c}(optional:{char}format specifier for thousands separator, e.g.,{c:,}){total}{t}(optional:{char}format specifier for thousands separator, e.g.,{t:,}){percentage}{percent}{p}(optional:.<num>fformat specifier to round to specified number of decimal places, e.g.,{p:.1f})
limited_format– A simplified format strings used when the terminal width is too small.sep– The separator string used to join multiple format strings.
The formats can additionally be styled by embedding ANSI from the operator-based API.
For more detailed information, see the ansi module documentation.
.set_chars()
def set_chars(self, chars: SeqOrSet[str], /) -> NoneSet the characters used to render the progress bar.
chars– A collection of characters ordered from full to empty progress:
The first character represents completely filled sections.
Intermediate characters create smooth transitions.
The last character represents empty sections.
IfNone, uses default Unicode block characters.
Example Usage
ProgressBar.set_chars(("█", "▓", "▒", "░", " ")).show_progress()
def show_progress(self, current: int, total: int, /, label: S | str | None = None) -> NoneShow or update the progress bar.
current– The current progress value (below0or greater thantotalhides the bar).total– The total value representing 100% progress (must be greater than0).label– An optional label which is inserted at the{label}or{l}placeholder.
.hide_progress()
def hide_progress(self) -> NoneHide the progress bar and restore normal terminal output.
.progress_context()
def progress_context(self, total: int, /, label: S | str | None = None) -> Generator[ProgressUpdater, None, None]Context manager for automatic cleanup. Returns a function to update progress.
total– The total value representing 100% progress (must be greater than0).label– An optional label which is inserted at the{label}or{l}placeholder.
The returned callable accepts keyword arguments.
At least one of these parameters must be provided:
current– Update the current progress value.label– Update the progress label.
Example Usage
with ProgressBar().progress_context(500, "Loading...") as update_progress:
update_progress(0) # Show empty bar at start.
for i in range(400):
# Do some work...
update_progress(i) # Update progress
update_progress("Finalizing...") # Update label.
for i in range(400, 500):
# Do some work...
update_progress(i, f"Finalizing ({i})") # Update both.Throbber
class Throbber(
self,
*,
label: S | str | None = None,
format: Sequence[TextRenderable] | TextRenderable = _DEFAULT_THROBBER_FORMAT,
sep: str = " ",
frames: tuple[str, ...] = FRAMES_STANDARD,
interval: float = 0.08,
)A terminal throbber for indeterminate processes with customizable appearance.
This class intercepts stdout to allow printing while the animation is active.
label– The current label text.format– The format string used to render the throbber, containing placeholders:{label}{l}{animation}{a}
frames– A tuple of strings representing the animation frames.interval– The time in seconds between each animation frame.
The format can additionally be styled by embedding ANSI from the operator-based API.
For more detailed information, see the ansi module documentation.
Example Usage
import time
from xulbux import S, Throbber
from xulbux.console import FRAMES_WINDMILL
throbber = Throbber(frames=FRAMES_WINDMILL)
throbber.start(S.BR.YELLOW("Initializing server..."))
time.sleep(2)
throbber.update_label(S.BR.GREEN("Connected successfully!"))
time.sleep(1)
throbber.stop().set_format()
def set_format(self, format: Sequence[TextRenderable] | TextRenderable, *, sep: str | None = None) -> NoneSet the format string used to render the throbber.
format– The format strings used to render the throbber, containing placeholders:{label}{l}{animation}{a}
sep– The separator string used to join multiple format strings.
The format can additionally be styled by embedding ANSI from the operator-based API.
For more detailed information, see the ansi module documentation.
.set_frames()
def set_frames(self, frames: SeqOrSet[str], /) -> NoneSet the frames used for the throbber animation.
frames– A collection of strings representing the animation frames.
.set_interval()
def set_interval(self, interval: int | float, /) -> NoneSet the time interval between each animation frame.
interval– The time in seconds between each animation frame.
.start()
def start(self, label: S | str | None = None, /) -> NoneStart the throbber animation and intercept stdout.
label– The label to display alongside the throbber.
.stop()
def stop(self) -> NoneStop and hide the throbber and restore normal terminal output.
.update_label()
def update_label(self, label: S | str | None, /) -> NoneUpdate the throbber's label text.
new_label– The new label text.
.context()
Context manager for automatic cleanup. Returns a function to update the label.
label– The label to display alongside the throbber.
The returned callable accepts a single parameter:
new_label– The new label text.
Example Usage
with Throbber().context("Starting...") as update_label:
time.sleep(2)
update_label("Processing...")
time.sleep(3)
update_label("Finishing...")
time.sleep(2)