Claude Code for sty: ANSI Styling for Python Terminals — Claude Skills 360 Blog
Blog / AI / Claude Code for sty: ANSI Styling for Python Terminals
AI

Claude Code for sty: ANSI Styling for Python Terminals

Published: April 1, 2028
Read time: 5 min read
By: Claude Skills 360

sty provides clean, composable ANSI escape codes for terminal colors and text effects. pip install sty. Named colors: from sty import fg, bg, ef, rs; print(fg.red + "Red" + rs.fg). fg.green, fg.blue, fg.yellow, fg.cyan, fg.magenta, fg.white, fg.black. Background: bg.red, bg.green, bg.blue, etc. Effect: ef.bold, ef.italic, ef.underline, ef.blink, ef.dim, ef.inverse, ef.hidden, ef.strike. Reset: rs.all (all attrs), rs.fg (fg only), rs.bg (bg only), rs.ef (effects only), rs.bold_dim, rs.blink, rs.inverse, rs.underline. True color (24-bit): fg(255, 0, 128) — R,G,B. bg(0, 128, 255). 256-color: fg(196) — index. bg(22). Compose: fg.red + ef.bold + "text" + rs.all. Extended: from sty import Style, RgbFg; fg.orange = Style(RgbFg(255, 150, 50)) — register custom. sty objects are strings: len(fg.red) == len("\033[31m"). Iterable: str.join("", [fg.blue, text, rs.fg]). Disable: from sty import mute; mute(fg, bg, ef, rs) — set all codes to "" for non-TTY. Re-enable: from sty import unmute. is_muted(). Works in f-strings: f"{fg.green}OK{rs.fg}". Claude Code generates sty styled output helpers, color maps, and terminal formatting libraries.

CLAUDE.md for sty

## sty Stack
- Version: sty >= 1.0 | pip install sty
- Named: fg.red + "text" + rs.fg | fg.green | bg.blue | ef.bold | ef.underline
- True color: fg(255, 0, 128) + "text" + rs.fg — 24-bit RGB
- 256-color: fg(196) | bg(22) — ANSI 256-color palette index
- Effects: ef.bold | ef.italic | ef.underline | ef.blink | ef.dim | ef.inverse
- Reset: rs.all (everything) | rs.fg | rs.bg | rs.ef (effects only)
- Mute: from sty import mute; mute(fg, bg, ef, rs) — strips codes for non-TTY

sty Terminal Styling Pipeline

# app/styling.py — sty ANSI colors, effects, and styled output helpers
from __future__ import annotations

import sys
from typing import Any

from sty import bg, ef, fg, rs
from sty import Style, RgbFg, RgbBg
from sty import mute, unmute


# ─────────────────────────────────────────────────────────────────────────────
# 1. Register custom colors
# ─────────────────────────────────────────────────────────────────────────────

# 24-bit custom colors
fg.orange   = Style(RgbFg(255, 165, 0))
fg.pink     = Style(RgbFg(255, 105, 180))
fg.purple   = Style(RgbFg(148, 0,   211))
fg.teal     = Style(RgbFg(0,   128, 128))
fg.gold     = Style(RgbFg(255, 215, 0))
fg.silver   = Style(RgbFg(192, 192, 192))

bg.orange   = Style(RgbBg(255, 165, 0))
bg.navy     = Style(RgbBg(0,   0,   128))
bg.dark     = Style(RgbBg(30,  30,  30))


# ─────────────────────────────────────────────────────────────────────────────
# 2. TTY detection and muting
# ─────────────────────────────────────────────────────────────────────────────

def setup_for_tty(stream=sys.stdout) -> None:
    """
    Mute all sty codes if the stream is not a TTY.
    Call once at startup: setup_for_tty(sys.stdout).
    """
    if not stream.isatty():
        mute(fg, bg, ef, rs)


def force_colors() -> None:
    """Re-enable colors even in non-TTY (e.g. piped to less -R)."""
    unmute(fg, bg, ef, rs)


# ─────────────────────────────────────────────────────────────────────────────
# 3. Styled string factories
# ─────────────────────────────────────────────────────────────────────────────

def styled(text: str, *codes: str) -> str:
    """
    Wrap text in one or more sty codes plus rs.all.
    styled("Hello", fg.green, ef.bold)
    """
    prefix = "".join(codes)
    return f"{prefix}{text}{rs.all}"


def bold(text: str, color: str = "") -> str:
    return styled(text, color, ef.bold) if color else styled(text, ef.bold)


def italic(text: str) -> str:
    return styled(text, ef.italic)


def underline(text: str, color: str = "") -> str:
    return styled(text, color, ef.underline) if color else styled(text, ef.underline)


# Semantic helpers
def success(text: str) -> str:
    return styled(text, fg.green, ef.bold)


def error(text: str) -> str:
    return styled(text, fg.red, ef.bold)


def warning(text: str) -> str:
    return styled(text, fg.yellow)


def info(text: str) -> str:
    return styled(text, fg.cyan)


def dim(text: str) -> str:
    return styled(text, ef.dim)


def highlight(text: str) -> str:
    return styled(text, fg.black + bg.yellow)


def code_inline(text: str) -> str:
    """Render inline code with dark background."""
    return styled(text, fg.white + bg.dark)


# ─────────────────────────────────────────────────────────────────────────────
# 4. Badge / label components
# ─────────────────────────────────────────────────────────────────────────────

BADGE_STYLES: dict[str, tuple[str, str]] = {
    "success": (fg.black + bg.green,   "green-on-black"),
    "error":   (fg.white + bg.red,     "white-on-red"),
    "warning": (fg.black + bg.yellow,  "black-on-yellow"),
    "info":    (fg.white + bg.blue,    "white-on-blue"),
    "debug":   (fg.white + bg.da_silva if hasattr(fg, "da_silva") else fg.white + bg.black, ""),
    "critical":(fg.white + bg.red + ef.bold, ""),
}


def badge(text: str, kind: str = "info") -> str:
    """
    Render a colored badge label.
    kind: "success" | "error" | "warning" | "info" | "debug" | "critical"
    """
    codes, _ = BADGE_STYLES.get(kind, (fg.white, ""))
    padded = f" {text} "
    return f"{codes}{padded}{rs.all}"


def level_badge(level: str) -> str:
    """Map a log level name to a colored badge."""
    mapping = {
        "DEBUG":    "debug",
        "INFO":     "info",
        "WARNING":  "warning",
        "ERROR":    "error",
        "CRITICAL": "critical",
        "SUCCESS":  "success",
    }
    return badge(f"{level:<8}", mapping.get(level.upper(), "info"))


# ─────────────────────────────────────────────────────────────────────────────
# 5. Separator and layout helpers
# ─────────────────────────────────────────────────────────────────────────────

def separator(char: str = "─", width: int = 80, color: str = "") -> str:
    """Horizontal separator line."""
    line = char * width
    return styled(line, color, ef.dim) if color else dim(line)


def header(text: str, width: int = 80, color: str = "") -> str:
    """Bold centered header with separator."""
    title = text.center(width)
    sep   = "═" * width
    c = color or fg.cyan
    return f"{styled(sep, c)}\n{styled(title, c, ef.bold)}\n{styled(sep, c)}"


def section(title: str) -> str:
    """Section label with underline."""
    return f"\n{bold(title, fg.blue)}\n{dim('─' * len(title))}"


def key_value(key: str, value: Any, key_width: int = 20) -> str:
    """Formatted key-value pair: key  value."""
    k = info(f"{key:<{key_width}}")
    v = str(value)
    return f"  {k} {v}"


def table_header(columns: list[str], widths: list[int]) -> str:
    """Render a styled table header row."""
    cells = [bold(col.ljust(w), fg.blue) for col, w in zip(columns, widths)]
    row   = "  " + "  ".join(cells)
    sep   = dim("  " + "  ".join("─" * w for w in widths))
    return f"{row}\n{sep}"


def table_row(values: list[Any], widths: list[int]) -> str:
    """Render a plain table row."""
    cells = [str(v).ljust(w) for v, w in zip(values, widths)]
    return "  " + "  ".join(cells)


# ─────────────────────────────────────────────────────────────────────────────
# 6. Palette viewer
# ─────────────────────────────────────────────────────────────────────────────

def print_named_colors() -> None:
    """Print all standard named sty colors."""
    named = ["black","red","green","yellow","blue","magenta","cyan","white",
             "li_black","li_red","li_green","li_yellow","li_blue","li_magenta",
             "li_cyan","li_white"]
    for name in named:
        code = getattr(fg, name, None)
        if code is not None:
            sample = f"  {code}{'█' * 8}{rs.fg}  fg.{name}"
            print(sample)


def print_rgb_gradient(r: int = 255, steps: int = 20) -> None:
    """Print a gradient from black to rgb(r, 255, 255) using 24-bit color."""
    for i in range(steps):
        v = int(255 * i / steps)
        block = fg(r, v, v) + "█" + rs.fg
        print(block, end="")
    print()


def print_256_palette() -> None:
    """Print the standard 256-color palette."""
    for i in range(256):
        end = "\n" if (i + 1) % 16 == 0 else ""
        print(f"{bg(i)}  {rs.bg}", end=end)
    print()


# ─────────────────────────────────────────────────────────────────────────────
# 7. Progress bar with sty colors
# ─────────────────────────────────────────────────────────────────────────────

def color_bar(
    value: float,
    total: float,
    width: int = 40,
    filled_char: str = "█",
    empty_char: str = "░",
) -> str:
    """Render a colored ASCII progress bar using sty."""
    pct  = min(1.0, max(0.0, value / total)) if total else 0.0
    fill = int(pct * width)
    bar  = filled_char * fill + empty_char * (width - fill)
    if pct >= 0.8:
        color = fg.green
    elif pct >= 0.4:
        color = fg.yellow
    else:
        color = fg.red
    return f"{color}[{bar}]{rs.fg} {pct*100:5.1f}%"


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== Named colors ===")
    for name in ["red", "green", "yellow", "blue", "cyan", "magenta", "white"]:
        code = getattr(fg, name)
        print(f"  {code}fg.{name}{rs.fg}")

    print("\n=== Effects ===")
    print(f"  {ef.bold}Bold{rs.ef}  {ef.italic}Italic{rs.ef}  "
          f"{ef.underline}Underline{rs.ef}  {ef.dim}Dim{rs.ef}")

    print("\n=== Semantic helpers ===")
    print(f"  {success('✔ Deployment succeeded')}")
    print(f"  {warning('⚠ Service degraded')}")
    print(f"  {error('✗ Connection refused')}")
    print(f"  {info('ℹ 42 records processed')}")
    print(f"  {highlight('HIGHLIGHTED')}")
    print(f"  {code_inline('npm run build')}")

    print("\n=== Badges ===")
    for kind in ["success", "error", "warning", "info", "critical"]:
        print(f"  {badge(kind.upper(), kind)}")

    print("\n=== Level badges ===")
    for level in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
        print(f"  {level_badge(level)} Some log message")

    print("\n=== Layout ===")
    print(header("Application Status Report", width=50))
    print(section("Database"))
    print(key_value("Connection", "postgresql://localhost:5432/app"))
    print(key_value("Pool size",  "10/10"))
    print(separator(width=50))

    print("\n=== Table ===")
    cols   = ["Name", "Status", "Uptime"]
    widths = [15,     10,       12]
    print(table_header(cols, widths))
    rows = [
        ["api",       success("running"), "2h 14m"],
        ["worker",    success("running"), "2h 14m"],
        ["scheduler", warning("paused"),  "—"],
    ]
    for row in rows:
        print(table_row(row, widths))

    print("\n=== Progress bars ===")
    for pct in [15, 45, 80, 100]:
        print(f"  {color_bar(pct, 100, width=30)}")

    print("\n=== 24-bit RGB gradient ===")
    print_rgb_gradient(r=255, steps=32)

    print("\n=== Custom colors ===")
    print(f"  {fg.orange}Orange{rs.fg}  {fg.pink}Pink{rs.fg}  "
          f"{fg.purple}Purple{rs.fg}  {fg.teal}Teal{rs.fg}  {fg.gold}Gold{rs.fg}")

For the colorama alternative — colorama translates ANSI codes to Windows console calls and is the standard for cross-platform color support, but its API is Fore.RED + text + Style.RESET_ALL; sty is more composable — fg.red, bg.blue, ef.bold are string objects that you concatenate freely, and mute(fg, bg, ef, rs) disables all codes at once for non-TTY output. For the termcolor alternative — termcolor’s colored("text", "red", "on_white", ["bold"]) is a one-liner that returns a complete styled string, which is convenient but limits composition; sty lets you build up codes independently (fg.red + ef.bold + bg.white + text + rs.all) and register custom 24-bit colors (fg.brand = Style(RgbFg(22, 121, 187))), making it better when you need a consistent color palette across a large codebase. The Claude Skills 360 bundle includes sty skill sets covering fg/bg/ef/rs objects, 24-bit fg(R,G,B)/bg(R,G,B) true color, 256-color fg(N)/bg(N) palette, ef.bold/italic/underline/dim effects, rs.all/fg/bg/ef selective reset, custom color registration with Style(RgbFg), mute()/unmute() for TTY detection, styled() composition helper, success/error/warning/info semantic helpers, badge()/level_badge() labeled chips, separator()/header()/section() layout, table_header()/table_row() formatting, and color_bar() colored progress. Start with the free tier to try ANSI terminal styling code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free