Formatting CLI Text in Python with textwrap
Building command-line interface (CLI) applications in Python often
requires presenting long strings, help menus, or multiline messages to
the user in a clean, readable fashion. The built-in
textwrap module provides automated text formatting
utilities designed to wrap, fill, indent, and trim text blocks. This
article explains the primary purposes of textwrap in Python
CLI tools, highlighting its essential functions and how it improves the
terminal user experience.
Preventing Awkward Terminal Line Breaks
By default, terminal emulators wrap lines strictly by character limits. When a long string reaches the edge of a terminal window, standard output splits words arbitrarily across two lines, severely reducing readability.
The primary purpose of textwrap is word-aware wrapping.
It ensures that line breaks occur at natural whitespace boundaries or
hyphens rather than mid-word.
Key Functions and Their CLI Applications
The textwrap module provides a set of high-level
convenience functions tailored to common formatting needs:
textwrap.fill(text, width=70): Wraps a single paragraph and returns a single string containing the wrapped lines separated by newline characters (\n). In a CLI, this is used to format long descriptions or error messages to match standard reading widths.textwrap.wrap(text, width=70): Similar tofill(), but returns a Python list of strings, with each string representing a single line. This is useful when you need to process or style lines individually before printing.textwrap.dedent(text): Removes any common leading whitespace from every line in a multiline string. In CLI development, help messages and documentation are frequently written as multiline docstrings, which naturally carry indentation from the surrounding code. Usingdedent()allows developers to keep readable source code without outputting unnecessary leading spaces to the terminal.textwrap.indent(text, prefix): Adds a specific prefix (such as spaces, tabs, or symbols like>) to the start of selected lines. This is ideal for rendering nested lists, code snippets, or block quotes within a CLI output.textwrap.shorten(text, width, placeholder="..."): Truncates a string to fit within a designated character limit, collapsing whitespace and appending an ellipsis while still breaking only on word boundaries. This is practical for CLI tables, summary views, and status listings where column width is constrained.
Dynamic Layouts Using Terminal Width
Hardcoding line lengths can cause visual inconsistencies on different
screens. When combined with Python’s os.get_terminal_size()
or shutil.get_terminal_size(), textwrap can
dynamically adapt output to fit the user's current terminal
dimensions:
import shutil
import textwrap
terminal_width = shutil.get_terminal_size().columns
wrapped_text = textwrap.fill(long_message, width=min(terminal_width, 80))
print(wrapped_text)By capping the width to an upper limit (such as 80 characters) or expanding to the terminal's boundary, applications maintain a balanced reading flow.
Consistent Indentation for Help Menus
CLI interfaces often require hierarchical visual structures, such as
command lists where descriptions appear indented beneath command names.
The TextWrapper class allows fine-grained control via
parameters like initial_indent and
subsequent_indent:
wrapper = textwrap.TextWrapper(
width=60,
initial_indent=" --help: ",
subsequent_indent=" "
)
print(wrapper.fill("Displays this help message and exits the application."))This ensures that wrapped lines align with the start of the description rather than resetting to the left margin, producing standard POSIX-style command line help output.