Skip to main content

prettier_console

Interactive, colorized command-line UI toolkit for Python — arrow-key menus, ASCII-art banners, colored text, and simple file/folder pickers.

Installation

pip install prettier-console

Requirements: Python 3.8+, and the keyboard package (used for arrow-key navigation and safe_input, will be installed with the package). On Linux, reading keyboard events usually requires running with sudo or granting input-group permissions.

Quickstart

import prettier_console as pc

def say_hello():
    print("Hello, world!")

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

options = [
    {
        "text": "hello world",
        "color": "green",
        "id": "hello",
        "func": {"body": say_hello},  # plain callable, no arguments
    },
    {
        "text": "hello, Ada",
        "color": "cyan",
        "id": "hello_ada",
        "func": {"body": say_hello_to, "param": ["Ada"]},   # positional argument(s)
    },
]

pc.home_menu("HOME", "Welcome!", options)
██╗  ██╗  ██████╗  ███╗   ███╗ ███████╗
██║  ██║ ██╔═══██╗ ████╗ ████║ ██╔════╝
███████║ ██║   ██║ ██╔████╔██║ █████╗  
██╔══██║ ██║   ██║ ██║╚██╔╝██║ ██╔══╝  
██║  ██║ ╚██████╔╝ ██║ ╚═╝ ██║ ███████╗
╚═╝  ╚═╝  ╚═════╝  ╚═╝     ╚═╝ ╚══════╝
=======================================
Welcome!

Choose from the following 3 options:
    >·1.hello world····<
      2.hello, Ada
      3.quit program

Pressing Enter on "hello world" calls hello_world() with no arguments; pressing Enter on "hello, Ada" calls hello_name("Ada"). Either way, once the handler returns, you're back at this menu — selecting "quit program" is what actually exits (via quit_program()). The options return and quit program is built into the menu(quit program for home_menu(), and return for menu()), so do not add them in the customized choice.

Usage

Colored output

from prettier_console import default_colored_output, colored_output

default_colored_output.print("Build succeeded", color="green")
default_colored_output.print("Warning: low disk space", color="yellow", background="black")

# Or make your own instance (e.g. bright variant)
bright = colored_output(bright=True)
bright.print("Critical error", color="red")

# Get a colored string without printing it (e.g. to embed in another message)
tag = default_colored_output.get_print_string_text("[OK]", color="green")
print(f"{tag} All tests passed")

Banners and headers (ASCII art)

pc.print_banner("prettier_console")
pc.print_header("v1.0 released", color="cyan")

Multi-line input is supported — \n starts a new row of large text:

pc.print_banner("quick brown fox\njumps over the\nlazy dog")

Yes/no and custom menus

answer = pc.print_yesorno("Delete this file?")   # returns 'y' or 'n'

choice = pc.print_selections(
    "Pick an environment:",
    [
        {"text": "Development", "color": "green", "id": "dev"},
        {"text": "Staging",     "color": "yellow", "id": "staging"},
        {"text": "Production",  "color": "red",    "id": "prod"},
    ],
)  # returns the chosen id, navigable with the up/down arrow keys

Full navigable menus

menu() builds a single screen; home_menu() is the entry point of your app (it adds a "quit" option instead of "back", and calls quit_program() when chosen).

def say_hello():
    return pc.menu(name="hello world", prompt="hello!", options=None)

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

options = [
    {
        "text": "Say hello",
        "color": "red",
        "id": "hello",
        "func": {"body": say_hello},
    },
    {
        "text": "Say hello to someone",
        "color": "blue",
        "id": "hello_name",
        "func": {"body": say_hello_to, "param": ["Ada"]},
    },
]

pc.home_menu(name="HOME", prompt="Welcome!", options=options)

Each option's func is called when selected — either a plain callable, or a {"body": fn, "param": [...]} dict for passing positional arguments. Returning "quit" from a handler exits the whole menu stack.

In order to build dynamic prompt that refreshes when the menu is redrawn, pass a function callback that returns a string.

hw_counter = 0

def say_hello():
    return pc.menu(name="hello world", prompt="hello!", options=None)

def prompt_builder():
    global hw_counter
    hw_counter += 1
    return f"hello world for {hw_counter} times!"

options = [
    {
        "text": "Say hello",
        "color": "red",
        "id": "hello",
        "func": {"body": say_hello},
    },
]

pc.home_menu(name="HOME", prompt=prompt_builder, options=options)

Safe input

name = pc.safe_input("What's your name? ")

A drop-in replacement for input() that guards against stray keypresses left over in the input buffer (falls back to normal input() if the keyboard backend isn't available, e.g. on some restricted environments).

File and folder pickers

files = pc.select_files(prompt="Select an image", filetypes=["jpg", "png"])   # opens a native file dialog, returns a tuple of paths or None
folder = pc.select_folder(prompt="Select a folder")               # prompt is provided by default. Opens a native folder dialog, returns a path or None

files = pc.select_files_window(["jpg", "png"])  # opens purely the file selection dialog, no prompt, echo or reselections, same return as select_files()
folder = pc.select_folder_window()  # opens purely the folder selection dialog, same return as select_folder()

Misc utilities

pc.clear_screen()                 # cross-platform 'cls'/'clear'
width = pc.display_width("你好 world")   # display width accounting for full-width CJK characters
pc.quit_program(0)                # clears the screen, prints a goodbye message, exits

CLI: adding custom ASCII-art fonts

The banner/header glyphs are stored as JSON under prettier_console/ascii_art_font/font/. You can add or replace a style from a plain-text font file (one row per line, glyph segments for A-Z + space separated by /):

python -m prettier_console.manage updatefont my_font.txt --style retro
python -m prettier_console.manage updatefont my_font.txt --banner   # overwrite the default banner style
python -m prettier_console.manage updatefont my_font.txt --header   # overwrite the default header style

The previous version of a style is automatically zipped into font/legacy_fonts/ before being overwritten.

API reference

Function Description
colored_output(bright=False) Class for producing ANSI-colored output.
display_width(text) Display width of a string, counting CJK characters as 2.
safe_input(prompt="") input() replacement resilient to buffered keypresses.
clear_screen() Clears the terminal, cross-platform.
select_files(prompt, file_types=) Native file-open dialog with prompt, result echoing, and reselection; returns selected paths or None.
select_folder(prompt) Native folder-select dialog with prompt, result echoing, and reselection; returns a path or None.
select_files_window(file_types) Opens native file-open dialog; returns selected paths or None.
select_folder_window() Opens native folder-select dialog; returns a path or None.
print_yesorno(prompt) Arrow-key Yes/No prompt; returns 'y' or 'n'.
print_selections(prompt, options) Arrow-key single-select prompt; returns the chosen option's id.
print_banner(text, color="white") Prints large ASCII-art banner text.
print_header(text, color="white") Prints smaller ASCII-art header text.
menu(name, prompt, options=None, home=False) Renders one navigable menu screen.
home_menu(name, prompt, options=None) Entry-point menu; quits the program via quit_program().
quit_program(code=0) Clears the screen, prints a goodbye message, exits.

Instances comes with the module

Instance Description
default_colored_output Shared colored_output instance, for using the functions without having to instantiate colored_output.
line_counter Built-in line counter that default_colored_output can mutate automatically to track how many lines are printed (notice: normal print does not count)

Worth noticing

When running, do not resize the window of powershell. Otherwise the formatting would break.

Avoid having wrapped text. The line_counter does not work well with wrapped text.

Metadata

Release files for prettier-console 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for prettier-console 1.2.0
File Size Uploaded
prettier_console-1.2.0.tar.gz 18.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for prettier-console 1.2.0
File Interpreter ABI Platform
prettier_console-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.1 kB

Release files / prettier_console-1.2.0.tar.gz

Download URL prettier_console-1.2.0.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f6d8af272ff01ed985312c25c5c6cf714412970248c4e69ae489cb1f9fd2758f
BLAKE2b-256 checksum
How to use checksums
606fbed68292b255ee3e13a5521967597eb48aa510faaf948297753e85c40b3e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Release files / prettier_console-1.2.0-py3-none-any.whl

Download URL prettier_console-1.2.0-py3-none-any.whl
Size 16.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bcc86825a3b86c39be809f2cfa0febe984a1a2eba6850da10b55a722c56c1ca7
BLAKE2b-256 checksum
How to use checksums
b172dc2a0674d51e98bd8af5c9c46f6c13ab99075d5a1c144a7cb4049e13ce08
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Release history Release notifications | RSS feed

1.6.0

2 release files

1.5.0

2 release files

1.4.4

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.1

2 release files

This release

1.2.0 This release

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page