Skip to content

ANSI API Reference

Auto-generated API documentation for the ansi module.

ansi

ANSI escape code primitives for terminal styling.

Zero dependencies, stdlib only, Python 3.10+.

Part of zerodep: https://github.com/Oaklight/zerodep Copyright (c) 2026 Peng Ding. MIT License.

Provides named colors, text attributes, 256-color and 24-bit true-color support, terminal capability detection, and utility helpers for stripping escape sequences and measuring visible text width.

Quick styling::

from ansi import style
print(style("Error!", fg="red", bold=True))
print(style("Success", fg="green", bg="black", italic=True))

Programmatic color construction::

from ansi import fg, bg, BOLD, RESET
print(f"{BOLD}{fg('blue')}hello{RESET}")
print(f"{fg('#ff8800')}orange text{RESET}")
print(f"{fg(214)}256-color{RESET}")
print(f"{bg(55)}{fg('white')}white on purple{RESET}")

Terminal detection::

from ansi import supports_color, color_depth
if supports_color():
    depth = color_depth()  # 16, 256, or 16777216

fg(color)

Return an ANSI escape for the given foreground color.

Parameters:

Name Type Description Default
color str | int | tuple[int, int, int]

A color name ("red", "bright_cyan"), hex string ("#ff8800"), 256-color index (0255), or RGB tuple ((255, 136, 0)).

required

Returns:

Type Description
str

An ANSI escape string.

Example::

print(fg("red") + "error" + RESET)
print(fg("#00ff00") + "green" + RESET)
print(fg(214) + "orange" + RESET)
print(fg((100, 200, 50)) + "custom" + RESET)
Source code in ansi/ansi.py
def fg(color: str | int | tuple[int, int, int]) -> str:
    """Return an ANSI escape for the given foreground color.

    Args:
        color: A color name (``"red"``, ``"bright_cyan"``), hex string
            (``"#ff8800"``), 256-color index (``0``–``255``), or RGB
            tuple (``(255, 136, 0)``).

    Returns:
        An ANSI escape string.

    Example::

        print(fg("red") + "error" + RESET)
        print(fg("#00ff00") + "green" + RESET)
        print(fg(214) + "orange" + RESET)
        print(fg((100, 200, 50)) + "custom" + RESET)
    """
    return _parse_color(color, 38)

bg(color)

Return an ANSI escape for the given background color.

Parameters:

Name Type Description Default
color str | int | tuple[int, int, int]

Same formats as :func:fg.

required

Returns:

Type Description
str

An ANSI escape string.

Source code in ansi/ansi.py
def bg(color: str | int | tuple[int, int, int]) -> str:
    """Return an ANSI escape for the given background color.

    Args:
        color: Same formats as :func:`fg`.

    Returns:
        An ANSI escape string.
    """
    return _parse_color(color, 48)

style(text, *, fg=None, bg=None, bold=False, dim=False, italic=False, underline=False, strikethrough=False, reverse=False, reset=True)

Wrap text with ANSI escape codes.

Parameters:

Name Type Description Default
text str

The string to style.

required
fg str | int | tuple[int, int, int] | None

Foreground color (name, hex, 256-index, or RGB tuple).

None
bg str | int | tuple[int, int, int] | None

Background color (same formats as fg).

None
bold bool

Apply bold weight.

False
dim bool

Apply dim/faint rendering.

False
italic bool

Apply italic style.

False
underline bool

Apply underline decoration.

False
strikethrough bool

Apply strikethrough decoration.

False
reverse bool

Swap foreground and background.

False
reset bool

Append a RESET sequence after text (default True).

True

Returns:

Type Description
str

The styled string.

Example::

style("Error!", fg="red", bold=True)
style("note", fg="cyan", italic=True)
style("warn", fg="yellow", bg="black", underline=True)
Source code in ansi/ansi.py
def style(
    text: str,
    *,
    fg: str | int | tuple[int, int, int] | None = None,  # noqa: A002
    bg: str | int | tuple[int, int, int] | None = None,  # noqa: A002
    bold: bool = False,
    dim: bool = False,
    italic: bool = False,
    underline: bool = False,
    strikethrough: bool = False,
    reverse: bool = False,
    reset: bool = True,
) -> str:
    """Wrap *text* with ANSI escape codes.

    Args:
        text: The string to style.
        fg: Foreground color (name, hex, 256-index, or RGB tuple).
        bg: Background color (same formats as *fg*).
        bold: Apply bold weight.
        dim: Apply dim/faint rendering.
        italic: Apply italic style.
        underline: Apply underline decoration.
        strikethrough: Apply strikethrough decoration.
        reverse: Swap foreground and background.
        reset: Append a ``RESET`` sequence after *text* (default ``True``).

    Returns:
        The styled string.

    Example::

        style("Error!", fg="red", bold=True)
        style("note", fg="cyan", italic=True)
        style("warn", fg="yellow", bg="black", underline=True)
    """
    parts: list[str] = []
    if bold:
        parts.append(BOLD)
    if dim:
        parts.append(DIM)
    if italic:
        parts.append(ITALIC)
    if underline:
        parts.append(UNDERLINE)
    if strikethrough:
        parts.append(STRIKETHROUGH)
    if reverse:
        parts.append(REVERSE)
    if fg is not None:
        parts.append(_parse_color(fg, 38))
    if bg is not None:
        parts.append(_parse_color(bg, 48))

    if not parts:
        return text

    prefix = "".join(parts)
    suffix = RESET if reset else ""
    return f"{prefix}{text}{suffix}"

supports_color(stream=None)

Check if the output stream supports ANSI color codes.

Respects the NO_COLOR environment variable (see <https://no-color.org/>_) and the FORCE_COLOR variable.

Parameters:

Name Type Description Default
stream Any

The output stream to check. Defaults to sys.stderr.

None

Returns:

Type Description
bool

True if the stream is a color-capable terminal.

Source code in ansi/ansi.py
def supports_color(stream: Any = None) -> bool:
    """Check if the output stream supports ANSI color codes.

    Respects the ``NO_COLOR`` environment variable
    (see `<https://no-color.org/>`_) and the ``FORCE_COLOR`` variable.

    Args:
        stream: The output stream to check.  Defaults to ``sys.stderr``.

    Returns:
        True if the stream is a color-capable terminal.
    """
    if os.environ.get("FORCE_COLOR"):
        return True
    if os.environ.get("NO_COLOR"):
        return False
    s = stream or sys.stderr
    if not hasattr(s, "isatty") or not s.isatty():
        return False
    if os.environ.get("TERM", "") == "dumb":
        return False
    return True

color_depth(stream=None)

Detect the color depth of the terminal.

Parameters:

Name Type Description Default
stream Any

The output stream to check. Defaults to sys.stderr.

None

Returns:

Type Description
int
  • 0 — no color support
int
  • 16 — standard 16 colors
int
  • 256 — 256 color palette
int
  • 16777216 — 24-bit true color
Source code in ansi/ansi.py
def color_depth(stream: Any = None) -> int:
    """Detect the color depth of the terminal.

    Args:
        stream: The output stream to check.  Defaults to ``sys.stderr``.

    Returns:
        - ``0`` — no color support
        - ``16`` — standard 16 colors
        - ``256`` — 256 color palette
        - ``16777216`` — 24-bit true color
    """
    if not supports_color(stream):
        return 0

    colorterm = os.environ.get("COLORTERM", "").lower()
    if _TRUECOLOR_RE.search(colorterm):
        return 16_777_216

    term = os.environ.get("TERM", "")
    if "256color" in term:
        return 256

    # Most modern terminals support at least 16 colors.
    return 16

strip_ansi(text)

Remove all ANSI escape sequences from text.

Parameters:

Name Type Description Default
text str

A string potentially containing ANSI escapes.

required

Returns:

Type Description
str

The plain text without escape sequences.

Example::

strip_ansi("\033[1m\033[31mhello\033[0m")  # "hello"
Source code in ansi/ansi.py
def strip_ansi(text: str) -> str:
    """Remove all ANSI escape sequences from *text*.

    Args:
        text: A string potentially containing ANSI escapes.

    Returns:
        The plain text without escape sequences.

    Example::

        strip_ansi("\\033[1m\\033[31mhello\\033[0m")  # "hello"
    """
    return _ANSI_ESCAPE_RE.sub("", text)

visible_len(text)

Return the visible character count of text, ignoring ANSI escapes.

Useful for aligning columns when text contains color codes.

Parameters:

Name Type Description Default
text str

A string potentially containing ANSI escapes.

required

Returns:

Type Description
int

The number of visible characters.

Source code in ansi/ansi.py
def visible_len(text: str) -> int:
    """Return the visible character count of *text*, ignoring ANSI escapes.

    Useful for aligning columns when text contains color codes.

    Args:
        text: A string potentially containing ANSI escapes.

    Returns:
        The number of visible characters.
    """
    return len(strip_ansi(text))

cursor_move(n=1, direction='up')

Return an ANSI escape to move the cursor.

Parameters:

Name Type Description Default
n int

Number of positions to move.

1
direction str

One of "up", "down", "forward", "back".

'up'

Returns:

Type Description
str

An ANSI escape string.

Raises:

Type Description
ValueError

If direction is not recognised.

Source code in ansi/ansi.py
def cursor_move(n: int = 1, direction: str = "up") -> str:
    """Return an ANSI escape to move the cursor.

    Args:
        n: Number of positions to move.
        direction: One of ``"up"``, ``"down"``, ``"forward"``, ``"back"``.

    Returns:
        An ANSI escape string.

    Raises:
        ValueError: If *direction* is not recognised.
    """
    codes = {"up": "A", "down": "B", "forward": "C", "back": "D"}
    if direction not in codes:
        raise ValueError(f"Unknown direction: {direction!r}. Valid: {', '.join(codes)}")
    return f"\033[{n}{codes[direction]}"