sparcli
Styled CLI output and interactive input widgets for Python, built directly on ANSI escape codes with no third-party dependencies.
sparcli is a native Python port of the Rust library of the same name. It renders styled text, tables, panels, trees and progress bars, and drives single-input prompts (text, password, number, confirm, select, fuzzy, date and more) – all from the standard library alone. It is meant for small, lightweight CLI tools: a single accent color, muted defaults, rounded borders, and graceful behavior under NOCOLOR or when output is piped. Heavy, full-screen retained TUIs are out of scope.
Highlights
- Output: styled text, inline markup, tables (colspan, rowspan, striping, wrapping, titles), panels, cards (a filled surface whose whole palette is derived from one accent color), alerts, rules, lists, trees, key-value lists, badges, progress bars, spinners, multi-progress, diffs, columns, live in-place display, pager, and the composition helpers align, pad and vstack.
- Input: confirm, text (validation, character filters, history, ghost autocomplete, dropdown), password, number (with a calculator), textarea, single and multi select, an inline fuzzy select, and a calendar date picker.
- A unified Theme for input and output, set once and overridable per call.
- Robust by design: prompts never raise on input, a RAII terminal guard restores the terminal, and results come back as values rather than exceptions.
- Zero dependencies: pure Python, standard library only, typed under strict basedpyright.
Installation
pip install py-sparcliThe distribution is named py-sparcli, but the import package is sparcli:
import sparcli
from sparcli import Panel, Table, TextInputsparcli requires Python 3.12 or newer.
Feature overview
| Category | Components | | --- | --- | | Text and style | Style, Color, Attribute, Span, Line, Text, markup | | Framing and layout | Panel, Card, Rule, Columns, align, pad, vstack, BorderType, Align, Edges, Title | | Data widgets | Table (Column, Cell), List (Marker), Tree (TreeNode), KeyValue, Diff, Badge, Alert (AlertKind) | | Progress and live | Spinner (SpinnerStyle), ProgressBar (ProgressStyle, Thresholds), MultiProgress, Live, Pager | | Input prompts | TextInput, PasswordInput, NumberInput, Confirm, Select, FuzzySelect, DatePicker, Textarea | | Prompt support | Outcome, History, Shortcut, validate, event | | Theming and terminal | Theme, theme, settheme, colorsupport, isinputtty, isoutputtty, termwidth |
Output example
Every output widget exposes print() to write to stdout, printto(writer) to capture the result, and render(maxwidth) to lay it out as a composable block. When stdout is not a terminal (a pipe, a file, or with NOCOLOR set), no escape codes are emitted.
from sparcli import Alert, Table
Alert.success("Build finished.").print()
Table().columns(["Name", "Status"]).row(["web-1", "online"]).row(
["db-1", "online"]
).striped(True).print()╭───────────────────╮
│ ✔ Build finished. │
╰───────────────────╯
╭───────┬────────╮
│ Name │ Status │
├───────┼────────┤
│ web-1 │ online │
│ db-1 │ online │
╰───────┴────────╯A Panel frames content with a rounded border and an optional title. A left-aligned title reads as part of the frame: one connecting border glyph sits before it, never a flush corner – unless the title is too wide for the frame, in which case it is truncated into the border rather than widening the panel.
from sparcli import Panel
Panel("All systems nominal.").title("Status").print()