Skip to main content

A batteries-included CLI UI kit on top of Rich

Project description

ChalkBox Logo

A batteries-included CLI UI kit on top of Rich

CI PyPI Python Poetry Ruff Type checking: mypy Security: bandit License Built on Rich

A batteries-included CLI UI kit built on top of Rich. ChalkBox provides consistent, themed, and composable components for building beautiful command-line interfaces with fail-safe defaults.

ChalkBox Demo

Why ChalkBox?

ChalkBox = Rich + Batteries Included + Fail-Safe + Smart Defaults

While Rich provides excellent terminal primitives, ChalkBox gives you production-ready components with graceful error handling, universal compatibility, and beautiful defaults out of the box.

Installation

pip install chalkbox

Upgrading from v1.2.0

Note: ChalkBox v2.0 introduced breaking changes to the theme customization API.

You're affected only if you customize themes programmatically:

  • set_theme(None, **{"colors.primary": "blue"})
  • theme.get("colors.primary")
  • theme.colors["primary"]

You're NOT affected if you:

  • ✓ Just use components normally: Alert.success(), Spinner(), Table()
  • ✓ Load themes from files: set_theme(Theme.from_file(path))

→ See v2.0 migration guide

Quick Start

from chalkbox import get_console, Spinner, Alert, Table
import time

console = get_console()

# Spinner with success/error states
with Spinner("Loading data") as spinner:
    time.sleep(2)
    spinner.success("Data loaded!")

# Severity-based alerts (6 levels: debug, info, success, warning, error, critical)
console.print(Alert.debug("Verbose mode enabled"))
console.print(Alert.info("Processing 1,234 records"))
console.print(Alert.success("Deployment complete"))
console.print(Alert.warning("API rate limit: 850/1000"))
console.print(Alert.error("Connection failed", details="Check network settings"))
console.print(Alert.critical("System shutdown in 60s", details="Save all work immediately"))

# Tables with severity styling
table = Table(headers=["Service", "Status", "Response Time"], row_styles="severity")
table.add_row("API", "✓ Running", "45ms", severity="success")
table.add_row("Cache", "⚠ Degraded", "230ms", severity="warning")
table.add_row("Queue", "✗ Down", "timeout", severity="error")
console.print(table)

Key Features

  • Fail-Safe Design - Graceful error handling with automatic fallbacks
  • Batteries Included - Common patterns pre-built (alerts, spinners, steppers, etc.)
  • Auto Secret Masking - Automatically masks passwords, keys, tokens
  • Non-TTY Support - Works in CI/CD, Docker, piped output
  • Live Dashboards - Real-time monitoring with terminal resize support
  • Theming System - Consistent styling via config/env/code
  • Context Managers - Clean resource handling for all stateful components

Components

Display & Content

Component Description
Alert 6-level severity alerts (debug/info/success/warning/error/critical)
StatusCard Composite status cards combining metrics, bars, and alerts
Table Auto-sizing tables with severity-based row styling
Section Organized content containers with optional subtitles
CodeBlock Syntax-highlighted code display with file reading support
JsonView JSON data visualization with pretty printing
Markdown Markdown rendering component
KeyValue Key-value displays with automatic secret masking
Tree Hierarchical data visualization with file system support

Progress & Status

Component Description
Spinner Loading indicators with success/fail/warning states
Progress Multi-task progress bars with ETA and thread-safe updates
Status Non-blocking status indicators for background operations
Stepper Multi-step workflow tracking with status indicators
DynamicProgress Auto-reordering progress tracker (sorts completed tasks by completion time)

Layout & Structure

Component Description
MultiPanel Complex layouts with grids and dashboards
ColumnLayout Responsive column layouts with equal/custom sizing
Divider Section dividers with multiple styles
Align Content alignment (horizontal & vertical)
Padding Theme-aware spacing wrapper with multiple patterns
Bar Horizontal bar charts and metrics visualization

Interactive Input

Component Description
Input Text input with validation
IntInput Integer input with range validation
FloatInput Float input with range validation
Select Choice selection from list
Confirm Yes/no confirmation prompts
View code examples for common components

Alert - Severity-based notifications

from chalkbox import Alert, get_console

console = get_console()

# 6 severity levels with automatic styling
console.print(Alert.debug("Verbose mode enabled"))
console.print(Alert.info("Processing 1,234 records"))
console.print(Alert.success("Deployment complete!"))
console.print(Alert.warning("API rate limit: 85% used"))
console.print(Alert.error("Connection failed", details="Check network settings"))
console.print(Alert.critical("System shutdown in 60s", details="Save all work"))

Spinner - Loading indicators

from chalkbox import Spinner
import time

# Context manager with automatic cleanup
with Spinner("Loading data") as spinner:
    time.sleep(2)
    spinner.success("Data loaded!")

# Or show errors
with Spinner("Connecting to database") as spinner:
    try:
        # connection logic
        spinner.success("Connected!")
    except Exception:
        spinner.error("Connection failed!")

Table - Structured data with severity styling

from chalkbox import Table, get_console

console = get_console()
table = Table(headers=["Service", "Status", "Uptime"], row_styles="severity")

# 11 severity levels available:
# Basic: debug, info, success, warning, error, critical, muted, primary
# Bold emphasis: important, active, urgent, highlighted
# Visual modifiers: orphaned (dimmed), deleted (strike-through)

table.add_row("API Gateway", "Running", "99.9%", severity="success")
table.add_row("Cache", "Degraded", "85.2%", severity="warning")
table.add_row("Message Queue", "Down", "0%", severity="error")
table.add_row("Admin User", "Online", "Active", severity="important")
table.add_row("Legacy Service", "Offline", "N/A", severity="orphaned")
table.add_row("Cancelled Task", "Removed", "N/A", severity="deleted")

console.print(table)

# Auto-expand: wide tables fill width, narrow tables stay compact
narrow = Table(headers=["Setting", "Value"], expand="auto")  # 2 cols: stays compact
wide = Table(headers=["A", "B", "C", "D", "E", "F", "G"], expand="auto")  # 7 cols: expands

# Customize threshold in ~/.chalkbox/theme.toml:
# [table]
# auto_expand_threshold = 7  # Tables with 7+ columns will expand

Progress - Multi-task tracking

from chalkbox import Progress
import time

# Track multiple tasks with ETA
with Progress() as progress:
    task1 = progress.add_task("Building", total=100)
    task2 = progress.add_task("Testing", total=50)
    task3 = progress.add_task("Deploying", total=25)

    for i in range(100):
        progress.update(task1, advance=1)
        if i < 50:
            progress.update(task2, advance=1)
        if i < 25:
            progress.update(task3, advance=1)
        time.sleep(0.01)

DynamicProgress - Auto-reordering progress tracker

Perfect for parallel task execution where completion order matters (web scraping, batch processing, etc.). Automatically sorts completed tasks by completion time (earliest first) using milliseconds.

from chalkbox import DynamicProgress
import time

with DynamicProgress() as progress:
    # Add tasks that will complete at different completion times
    slow = progress.add_task("Slow API")
    fast = progress.add_task("Fast API")
    medium = progress.add_task("Medium API")

    # Simulate different completion times
    time.sleep(0.5)
    progress.update(fast, completed=100)     # Completes in 0.5s

    time.sleep(0.5)
    progress.update(medium, completed=100)   # Completes in 1.0s

    time.sleep(1.0)
    progress.update(slow, completed=100)     # Completes in 2.0s

    # Completed section will show: Fast API (0:00), Medium API (0:01), Slow API (0:02)

KeyValue - Configuration display with secret masking

from chalkbox import KeyValue, get_console

console = get_console()
kv = KeyValue(title="System Configuration")

kv.add("Region", "us-east-1")
kv.add("Environment", "production")
kv.add("API URL", "https://api.example.com")
kv.add("API Key", "sk-1234567890abcdef")        # Automatically masked as "sk******ef"
kv.add("Database Password", "super_secret_123") # Automatically masked

console.print(kv)

StatusCard - Composite status displays

from chalkbox import StatusCard, Alert, get_console

console = get_console()

# StatusCard combines metrics, bars, and alerts for rich status displays
card = StatusCard(
    title="API Gateway",
    status="warning",
    subtitle="gateway-prod-01",
    metrics={"Uptime": "15d 3h", "Requests/sec": "1,234", "Error Rate": "0.8%"},
    bars=[
        ("Throughput", 85.0, 100.0, "warning"),  # Explicit severity (4-tuple)
        ("Response Time", 145.0, 200.0, "success"),
    ],
    alert=Alert.warning("Rate limit approaching", details="85% of quota used")
)

console.print(card)

# Or use auto-calculated severity with thresholds
thresholds = {"CPU": (70.0, 90.0), "Memory": (80.0, 95.0)}  # (warning%, error%)
card = StatusCard(
    title="Server Monitor",
    status="healthy",
    bars=[
        ("CPU", 45.0, 100.0),     # 3-tuple: severity auto-calculated
        ("Memory", 12.8, 16.0),
    ],
    bar_thresholds=thresholds
)

console.print(card)

Stepper - Workflow tracking with mixed states

from chalkbox import Stepper, get_console

console = get_console()
stepper = Stepper()

stepper.add_step("Initialize environment")
stepper.add_step("Install dependencies")
stepper.add_step("Run migrations")
stepper.add_step("Deploy application")
stepper.add_step("Run health checks")

# Update step statuses
stepper.complete(0)  # ● Initialize environment
stepper.complete(1)  # ● Install dependencies
stepper.fail(2)      # ✖ Run migrations (failed!)
stepper.skip(3)      # ⊘ Deploy application (skipped due to failure)
stepper.skip(4)      # ⊘ Run health checks (skipped)

console.print(stepper)

Explore more examples: demos/components/ | demos/showcases/

Theming

Customize ChalkBox colors and glyphs by creating ~/.chalkbox/theme.toml:

[colors]
primary = "cyan"
success = "green"
warning = "yellow"
error = "red"
info = "blue"

[glyphs]
success = "✓"
error = "✗"
warning = "⚠"
info = "i"

[spacing]
default = 1
section = 2

[borders]
default = "rounded"

You can also set theme values via environment variables using the pattern:

CHALKBOX_THEME_<CATEGORY>_<KEY>=<VALUE>

Examples:

export CHALKBOX_THEME_COLORS_PRIMARY=magenta
export CHALKBOX_THEME_GLYPHS_SUCCESS="[OK]"
export CHALKBOX_THEME_SPACING_DEFAULT=2
export CHALKBOX_THEME_BORDERS_STYLE=heavy
View all available environment variables

Colors (12 variables)

CHALKBOX_THEME_COLORS_PRIMARY=cyan
CHALKBOX_THEME_COLORS_SECONDARY=blue
CHALKBOX_THEME_COLORS_SUCCESS=green
CHALKBOX_THEME_COLORS_WARNING=yellow
CHALKBOX_THEME_COLORS_ERROR=red
CHALKBOX_THEME_COLORS_INFO=blue
CHALKBOX_THEME_COLORS_MUTED="dim white"
CHALKBOX_THEME_COLORS_ACCENT=bright_cyan
CHALKBOX_THEME_COLORS_BACKGROUND=default
CHALKBOX_THEME_COLORS_TEXT=default
CHALKBOX_THEME_COLORS_DEBUG="dim cyan"
CHALKBOX_THEME_COLORS_CRITICAL=bright_red

Glyphs (16 variables)

CHALKBOX_THEME_GLYPHS_SUCCESS=CHALKBOX_THEME_GLYPHS_ERROR=CHALKBOX_THEME_GLYPHS_WARNING=CHALKBOX_THEME_GLYPHS_INFO=i
CHALKBOX_THEME_GLYPHS_DEBUG=CHALKBOX_THEME_GLYPHS_CRITICAL=CHALKBOX_THEME_GLYPHS_ARROW=CHALKBOX_THEME_GLYPHS_BULLET=CHALKBOX_THEME_GLYPHS_CHECK=CHALKBOX_THEME_GLYPHS_CROSS=CHALKBOX_THEME_GLYPHS_SPINNER="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
CHALKBOX_THEME_GLYPHS_PENDING=CHALKBOX_THEME_GLYPHS_RUNNING=CHALKBOX_THEME_GLYPHS_COMPLETE=CHALKBOX_THEME_GLYPHS_FAILED=CHALKBOX_THEME_GLYPHS_SKIPPED=

Spacing (6 variables)

CHALKBOX_THEME_SPACING_XS=0
CHALKBOX_THEME_SPACING_SM=1
CHALKBOX_THEME_SPACING_DEFAULT=1
CHALKBOX_THEME_SPACING_MD=2
CHALKBOX_THEME_SPACING_LG=3
CHALKBOX_THEME_SPACING_XL=4

Borders (4 variables)

CHALKBOX_THEME_BORDERS_STYLE=rounded
CHALKBOX_THEME_BORDERS_PANEL=rounded
CHALKBOX_THEME_BORDERS_TABLE=rounded
CHALKBOX_THEME_BORDERS_SECTION=rounded

Valid border styles: rounded, heavy, double, square, ascii

Or programmatically in your code:

from chalkbox import set_theme

# Set individual values
set_theme({
    "colors.primary": "magenta",
    "colors.success": "bright_green",
})

# Or load a custom theme file
from chalkbox.core.theme import Theme
from pathlib import Path

custom_theme = Theme.from_file(Path("~/.chalkbox/theme-dark.toml").expanduser())
set_theme(custom_theme)

Examples

See the demos directory on GitHub for examples including component demos, real-world showcases, and workflow simulations.

Documentation

Full documentation site coming soon! For now, explore the many examples in https://github.com/bulletinmybeard/chalkbox/demos/.

ChalkBox vs Rich

ChalkBox is built on top of Rich, not as a replacement:

Feature Rich ChalkBox
Fail-Safe Can raise exceptions Handles errors gracefully
Patterns Low-level primitives High-level components
Configuration Manual styling Smart defaults + theming
Secret Masking Manual Automatic
Non-TTY Manual handling Automatic

Use ChalkBox when: Building CLI tools, need consistency, want fail-safe components Use Rich when: Need maximum flexibility, building custom visuals, library development

Mix both freely! ChalkBox components return Rich renderables:

from chalkbox import Alert
from rich.panel import Panel
from rich.console import Console

console = Console()
panel = Panel(Alert.success("Done!"), title="Status")
console.print(panel)

Requirements

  • Python 3.12+
  • Rich >= 14.2.0

Why Python 3.12+? ChalkBox uses modern Python features for clean code and better type hints.

Contributing

I welcome contributions! See CONTRIBUTING.md for:

  • Development setup and workflow
  • Coding standards and best practices
  • How to submit pull requests
  • Testing and quality checks

License

MIT License - see LICENSE file for details.

ChalkBox is built on Rich by Textualize, also MIT licensed.

Credits

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

chalkbox-2.2.0.tar.gz (51.3 kB view details)

Uploaded Source

Built Distribution

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

chalkbox-2.2.0-py3-none-any.whl (53.1 kB view details)

Uploaded Python 3

File details

Details for the file chalkbox-2.2.0.tar.gz.

File metadata

  • Download URL: chalkbox-2.2.0.tar.gz
  • Upload date:
  • Size: 51.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.13.7 Darwin/24.6.0

File hashes

Hashes for chalkbox-2.2.0.tar.gz
Algorithm Hash digest
SHA256 2b86cd192693d2faf45102a2d1019a315241cb35cd07180f1b087d3fd140cb73
MD5 cd13757f65391f74375fb4a307bd8034
BLAKE2b-256 7975970c8e37962102e308240fc4e41b39ee7329c6c71568490a260545946267

See more details on using hashes here.

File details

Details for the file chalkbox-2.2.0-py3-none-any.whl.

File metadata

  • Download URL: chalkbox-2.2.0-py3-none-any.whl
  • Upload date:
  • Size: 53.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.13.7 Darwin/24.6.0

File hashes

Hashes for chalkbox-2.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 72619355c9775035f23bfa5d0a61000c5798a302897b425f087401f4c2588cad
MD5 f9c0c2541f0265309460339f435086f9
BLAKE2b-256 2afe6ffb5c6cd6f6d67578e699ac6a66bdf1007badc08a7f2d259c3646e7ee09

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