Skip to main content

Rcolor Banner

🎨 Rcolor

High-Performance, Terminal-Aware Color & ANSI Styling Engine for Python

PyPI Python Platform License CI CodeQL Downloads


Random Foreground Colors Rainbow Text Output Backgrounds and Styles

Sample console outputs generated dynamically with Rcolor.


🌟 Introduction

Make your CLI applications look stunning with zero configuration.

Rcolor is an ultra-fast, zero-bloat Python library designed to bring colorful foregrounds, vibrant background highlights, terminal font styles, and per-character rainbow output to your terminal. Equipped with automatic terminal capability detection, Rcolor dynamically detects color depths (TrueColor > 256 colors > 16 colors > Plain Text) and automatically downsamples 256-color palettes to standard ANSI colors on restricted terminals—ensuring your terminal output looks flawless on Linux, macOS, and Windows.


🗺️ Quick Navigation

🚀
Quick Start
Get started in seconds
✨
Key Features
What Rcolor can do
🖥️
Terminal Matrix
Cross-platform compatibility
🧬
Architecture
Color detection pipeline
⚡
Benchmarks
Up to 327x faster
📖
Usage Guide
Complete code examples
🎨
Custom Palettes
JSON schema & loading
📚
API Reference
Full function signature table
🔍
Troubleshooting
Fix common CLI issues
🤝
Contributing
Tests & development

🚀 Quick Start

Get colorful terminal output in 3 simple commands:

# 1. Install or upgrade Rcolor from PyPI
pip install -U Rcolor

# 2. Print an automatically optimized random colorful message
python -c "import Rcolor; print(Rcolor.auto_fg('✨ Hello Beautiful Terminal! ✨'))"

# 3. Print per-character rainbow output
python -c "import Rcolor; print(Rcolor.rainbow_fg('🌈 Dynamic Rainbow Console Output'))"

✨ Key Features

Feature Description Highlight
Lightning-Fast Execution Built on precomputed tuples with zero disk I/O at runtime and $O(N)$ string joins. ⚡ 1.8 µs per call (~327x faster)
Intelligent Terminal Detection Automatically inspects environment variables, TTY streams, and OS console APIs. 🧠 Auto TrueColor / 256 / 16 / None
Automatic Downgrading Maps 256-color escape codes to the nearest ANSI 16 color via Euclidean RGB distance. 🎯 Flawless legacy terminal fallback
Contrast Guard Dynamically enforces WCAG relative luminance contrast ratios ($\ge 4.0:1$) for dual styling. 👁️ Guaranteed text readability
Curated Tone Presets Filter colors by cohesive aesthetic tones: neon, pastel, warm, and cool. 🎨 High-end palette curation
Smooth Linear Gradients Linear per-character color interpolation with multi-stop presets and TrueColor depth. 🌈 Seamless gradient banners
Universal Standards Compliance Respects NO_COLOR, FORCE_COLOR, CLICOLOR, and pipe redirections natively. 🛡️ Clean CLI & CI logs
External JSON Palette Color definitions stored in Rcolor/data/colors.json, loaded lazily on first access. 📦 Clean architecture & lazy load
Custom Palette Support Load your own brand or project themes via Rcolor.load_palette(). 🎨 Full JSON schema flexibility
100% Backward Compatibility All original v3.0 public APIs remain functional with identical arguments and return types. 🔒 Zero breaking API changes
Fully Typed (PEP 561) Includes py.typed marker and comprehensive type hints for IDE autocompletion. 💡 Type checker friendly

🖥️ Terminal Compatibility Matrix

Rcolor automatically detects console capabilities and delivers optimal rendering:

Terminal / Platform TrueColor (24-bit) 256 Colors (8-bit) 16 Colors (4-bit) Notes
Windows Terminal ✅ Full ✅ Full ✅ Full Natively detected via WT_SESSION
PowerShell 7+ ✅ Full ✅ Full ✅ Full Native VT support on modern Windows builds
Legacy cmd.exe 🔄 Auto-Downgraded 🔄 Auto-Downgraded ✅ Full Uses colorama VT initialization when available
GNOME Terminal ✅ Full ✅ Full ✅ Full Detected via COLORTERM=truecolor
Konsole (KDE) ✅ Full ✅ Full ✅ Full Full 24-bit TrueColor rendering
iTerm2 (macOS) ✅ Full ✅ Full ✅ Full Detected via TERM_PROGRAM=iTerm.app
Terminal.app (macOS) 🔄 Auto-Downgraded ✅ Full ✅ Full Detected via TERM_PROGRAM=Apple_Terminal
tmux / screen ✅ Full ✅ Full ✅ Full Handles nested terminal session strings
VS Code Terminal ✅ Full ✅ Full ✅ Full Detected via TERM_PROGRAM=vscode
PyCharm / IntelliJ ✅ Full ✅ Full ✅ Full Detected via PYCHARM_HOSTED / TERMINAL_EMULATOR
Jupyter / IPython 🔄 Auto-Downgraded ✅ Full ✅ Full Native ANSI support in web notebook cells
CI Logs / Pipes (> file) 🚫 Disabled 🚫 Disabled 🚫 Disabled Output safely stripped to plain text
🔍 How Automatic Capability Detection & Fallback Hierarchy Works

Rcolor inspects your execution context using the following deterministic hierarchy:

  1. Explicit Standards: NO_COLOR (always plain text) > FORCE_COLOR (0/1/2/3) > CLICOLOR_FORCE > CLICOLOR.
  2. Stream Target: sys.stdout.isatty() verifies output is attached to an interactive terminal rather than a log file or redirected pipe.
  3. IDE / Notebook Isolation: Detects Jupyter notebooks (ipykernel) and IDLE (idlelib).
  4. Multiplexers & SSH: Detects tmux, screen, and SSH_CONNECTION sessions.
  5. Windows VT Engine: Activates Windows Virtual Terminal Processing on Windows 10/11 or initializes colorama fallback.
  6. Nearest-Color Downgrade: If 256 colors are requested on an ANSI 16 console, colors are projected into standard 16 space via Euclidean RGB distance ($O(1)$ lookup table).

🧬 Detection & Downgrading Architecture

The ASCII diagram below illustrates how Rcolor determines color capabilities and renders output:

               +----------------------------------+
               |  User calls Rcolor function     |
               |  (e.g., auto_fg, foreground)    |
               +-----------------+----------------+
                                 |
                                 v
               +----------------------------------+
               | Check NO_COLOR or stdout != TTY  |
               +-----------------+----------------+
                                / \
                        YES    /   \   NO
               +--------------+     +-------------------+
               | Return plain |     | Check FORCE_COLOR |
               | text string  |     | or COLORTERM/TERM |
               +--------------+     +---------+---------+
                                              |
                   +--------------------------+--------------------------+
                   |                          |                          |
                   v                          v                          v
          [ TrueColor / 256 ]            [ 16-Color ]             [ Dumb / None ]
                   |                          |                          |
        +----------+----------+     +---------+----------+      +--------+---------+
        | Use 256-color code  |     | Map 256 color to   |      | Output plain     |
        | (\033[38;5;{id}m)   |     | nearest ANSI 16 via|      | string without   |
        |                     |     | RGB Euclidean dist |      | ANSI escapes     |
        +----------+----------+     +---------+----------+      +--------+---------+
                   |                          |                          |
                   +--------------------------+--------------------------+
                                              |
                                              v
                              +-------------------------------+
                              | Append clean '\033[0m' reset  |
                              +-------------------------------+

⚡ Benchmarks

Benchmarks measured on Python 3.14 comparing Rcolor v3.0.1 (legacy) vs Rcolor v3.1.0 (current):

Metric Legacy (v3.0.1) Optimized (v3.1.0) Speedup Factor
Import Time (fresh) 0.673 ms 1.601 ms Lazy zero-cost imports
foreground() call latency 250.91 µs 1.85 µs 135.7x faster 🚀
rainbow_fg() (1,000 chars) 147.40 ms 0.45 ms 327.1x faster 🚀

To reproduce these measurements locally:

python benchmarks/bench.py
⚙️ Benchmark Reproduction & Methodology Details

All benchmarks use Python's built-in timeit module:

  • Import Time: Evaluates fresh module imports after removing Rcolor from sys.modules across 200 iterations.
  • Function Latency: Evaluates 10,000 iterations of Rcolor.foreground("Hello, World!").
  • Rainbow Throughput: Evaluates 200 iterations of Rcolor.rainbow_fg("A" * 1000) measuring per-character join performance.

📖 Usage Guide

1. Basic Importing

import Rcolor

# Or import specific functions
from Rcolor import (
    foreground,
    background,
    style,
    rainbow_fg,
    standard_fg,
    standard_bg,
    standard_rainbow_fg,
    auto_fg,
    auto_bg,
    foreground_background,
    foreground_style,
    background_style,
    foreground_background_style,
)

2. Automatic Terminal-Aware Colors (auto_fg / auto_bg)

Recommended for general use. Chooses 256-color when available, standard 16-color on restricted consoles, and plain text in non-TTY environments:

import Rcolor

# Automatically styled foreground
print(Rcolor.auto_fg("This text adapts to your terminal capabilities!"))

# Automatically styled background
print(Rcolor.auto_bg("Highlighted text with automatic color selection!"))

3. Extended 256-Color Palette (foreground / background)

Applies a random color from the complete 256-color palette. If executed on a 16-color terminal, Rcolor automatically downsamples to the closest ANSI color:

# Random 256 foreground color
print(Rcolor.foreground("Vibrant 256-color foreground"))

# Random 256 background color
print(Rcolor.background("Vibrant 256-color background"))

4. Standard 16-Color Palette (standard_fg / standard_bg)

Guaranteed compatibility with all legacy ANSI terminals:

# Standard 16 ANSI foreground
print(Rcolor.standard_fg("Standard ANSI foreground color"))

# Standard 16 ANSI background
print(Rcolor.standard_bg("Standard ANSI background color"))

5. Font Styles (style)

Applies ANSI text attributes such as bold, dim, italic, and underline:

# Random text style
print(Rcolor.style("Bold, dim, italic, or underlined text!"))

6. Per-Character Rainbow Effects (rainbow_fg / standard_rainbow_fg)

Colorizes every character in the string individually:

# 256-color rainbow (with auto-downgrade)
print(Rcolor.rainbow_fg("Every single character has a unique random color!"))

# Standard 16-color rainbow
print(Rcolor.standard_rainbow_fg("Standard 16-color rainbow string!"))

7. Composite Styling & Readability Contrast Guard

Apply multiple ANSI attributes simultaneously. foreground_background automatically enforces a Contrast Guard based on WCAG 2.1 relative luminance, ensuring the foreground is always crisp and readable against the chosen background:

# Guaranteed readable foreground on background (min_contrast default is 4.0)
print(Rcolor.foreground_background("Always readable text!"))

# Customize contrast ratio (e.g. 7.0:1 for high contrast)
print(Rcolor.foreground_background("High contrast banner", min_contrast=7.0))

# Foreground + Font Style
print(Rcolor.foreground_style("Random foreground AND font style"))

# Background + Font Style
print(Rcolor.background_style("Random background AND font style"))

# Foreground + Background + Font Style with Contrast Guard
print(Rcolor.foreground_background_style("Full composite random styling!"))

8. Curated Tone Presets (neon, pastel, warm, cool)

Instead of pure white-noise randomness, style your console with cohesive aesthetic color themes:

# Vibrant electric neon tones
print(Rcolor.foreground("Neon cyan, lime, magenta & electric orange", tone="neon"))

# Soft, elegant pastel tones
print(Rcolor.foreground("Soft lavender, mint, pastel pink & baby blue", tone="pastel"))

# Warm sunset and amber tones
print(Rcolor.foreground("Rich red, orange, gold & amber tones", tone="warm"))

# Cool ocean and frost tones
print(Rcolor.foreground("Deep blue, cyan, teal & sapphire tones", tone="cool"))

# Tone presets work with auto_fg, auto_bg, and background too:
print(Rcolor.auto_fg("Automated neon theme", tone="neon"))
print(Rcolor.background("Pastel card background", tone="pastel"))

9. Smooth Linear Gradients & Multi-Stop Rainbow

Generate seamless character-by-character color transitions with TrueColor depth and automatic terminal fallback:

# 2-stop gradient from hex colors
print(Rcolor.gradient_fg("Smooth cyberpunk transition!", start="#ff007f", end="#00f0ff"))

# 2-stop gradient from RGB tuples
print(Rcolor.gradient_fg("Deep blue into lime green", start=(0, 0, 255), end=(0, 255, 0)))

# Built-in multi-stop presets: 'rainbow', 'neon', 'sunset', 'warm', 'cool', 'pastel', 'cyberpunk', 'ocean'
print(Rcolor.gradient_fg("Sunset horizon across characters", preset="sunset"))
print(Rcolor.gradient_fg("Electric cyberpunk aesthetic", preset="cyberpunk"))

# Instant smooth multi-stop rainbow text
print(Rcolor.gradient_rainbow("A gorgeous smooth rainbow gradient banner across your terminal!"))

10. ANSI Strip Utility (strip_color)

Cleanly calculate visible string lengths and align formatted CLI tables or progress boxes:

colored_banner = Rcolor.gradient_rainbow("Hello World")

# Strip ANSI codes for clean length measurement
plain_banner = Rcolor.strip_color(colored_banner)
print(len(plain_banner))  # Correctly prints 11, ignoring escape sequences!

🎨 Custom Palette Support

You can supply custom palettes at runtime using Rcolor.load_palette().

JSON Schema

Custom palettes must adhere to the following schema:

{
  "schema_version": 1,
  "standard": [
    {
      "id": 0,
      "name": "brand_blue",
      "fg": 34,
      "bg": 44,
      "rgb": [0, 102, 204],
      "hex": "#0066cc"
    }
  ],
  "extended": [
    {
      "id": 33,
      "name": "brand_accent",
      "rgb": [0, 153, 255],
      "hex": "#0099ff"
    }
  ],
  "styles": {
    "bold": 1,
    "underline": 4
  }
}

Loading a Custom Palette in Python

import Rcolor

# Load palette from a JSON file
Rcolor.load_palette("my_brand_palette.json")

# Or load from an in-memory dictionary
Rcolor.load_palette({
    "schema_version": 1,
    "standard": [{"id": 0, "name": "primary", "fg": 32, "bg": 42}],
    "extended": [{"id": 46, "name": "bright_green"}],
    "styles": {"bold": 1}
})

# Reset back to default built-in palette at any time
Rcolor.reset_palette()

print(Rcolor.foreground("Styled with custom palette!"))
📋 Complete Formal JSON Schema for Custom Palettes
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "RcolorPalette",
  "type": "object",
  "required": ["schema_version", "standard", "extended", "styles"],
  "properties": {
    "schema_version": { "type": "integer", "enum": [1] },
    "standard": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "name", "fg", "bg"],
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "fg": { "type": "integer" },
          "bg": { "type": "integer" },
          "rgb": { "type": "array", "items": { "type": "integer" } },
          "hex": { "type": "string" }
        }
      }
    },
    "extended": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id"],
        "properties": {
          "id": { "type": "integer", "minimum": 0, "maximum": 255 },
          "name": { "type": "string" },
          "rgb": { "type": "array", "items": { "type": "integer" } },
          "hex": { "type": "string" }
        }
      }
    },
    "styles": {
      "type": "object",
      "additionalProperties": { "type": "integer" }
    }
  }
}

📚 API Reference

Function Parameters Return Type Description
auto_fg(*user_input, tone=None) *user_input: Any, tone: str | None str Terminal-aware random foreground color (256/16/None), optional tone preset.
auto_bg(*user_input, tone=None) *user_input: Any, tone: str | None str Terminal-aware random background color (256/16/None), optional tone preset.
foreground(*user_input, tone=None) *user_input: Any, tone: str | None str Random 256-color foreground with auto-downgrade, optional tone preset ("neon", "pastel", "warm", "cool").
background(*user_input, tone=None) *user_input: Any, tone: str | None str Random 256-color background with auto-downgrade, optional tone preset.
standard_fg(*user_input) *user_input: Any str Random standard ANSI 16 foreground color.
standard_bg(*user_input) *user_input: Any str Random standard ANSI 16 background color.
style(*user_input) *user_input: Any str Random ANSI text style (bold, dim, underline, etc.).
rainbow_fg(user_input) user_input: Any str Per-character random 256-color rainbow string.
standard_rainbow_fg(user_input) user_input: Any str Per-character random 16-color rainbow string.
gradient_fg(user_input, start=..., end=..., preset=None) user_input: Any, ... str Smooth linear color gradient with auto TrueColor/256/16/None fallback.
gradient_rainbow(user_input) user_input: Any str Smooth multi-stop linear rainbow gradient across text.
foreground_background(*user_input, min_contrast=4.0) *user_input: Any, min_contrast: float str Combined random fg and bg with WCAG Contrast Guard readability guarantee.
foreground_style(*user_input) *user_input: Any str Combined random foreground and style.
background_style(*user_input) *user_input: Any str Combined random background and style.
foreground_background_style(*user_input, min_contrast=4.0) *user_input: Any, min_contrast: float str Combined random fg, bg, and style with WCAG Contrast Guard.
strip_color(text) text: str str Strips all ANSI escape sequences for width and alignment calculations.
contrast_ratio(rgb1, rgb2) rgb1: Sequence[int], rgb2: Sequence[int] float Computes WCAG 2.1 relative contrast ratio between two RGB colors (1.0 to 21.0).
relative_luminance(rgb) rgb: Sequence[int] float Calculates WCAG relative luminance ($L \in [0.0, 1.0]$).
load_palette(source) source: str | Path | dict Palette Loads and activates custom color palette.
reset_palette() None None Resets active palette back to default built-in palette.
detect_color_level() None ColorLevel Detects terminal color capability level without caching.
get_color_level() None ColorLevel Returns current terminal color capability level (cached).
set_color_level(level) level: ColorLevel | None None Manually overrides or resets color level.

🔍 Troubleshooting

Issue Cause Solution
Output shows raw escape codes like \033[38;5;12m Terminal does not interpret ANSI sequences (e.g. Windows legacy cmd without VT). Ensure colorama is installed, or set environment variable FORCE_COLOR=1.
Output appears completely uncolored NO_COLOR is set, or output is redirected to a file or pipe. Check echo $NO_COLOR. If writing to terminal pipes, pass FORCE_COLOR=1 or CLICOLOR_FORCE=1.
Colors look washed out or different on remote SSH Remote terminal reports TERM=xterm instead of xterm-256color. Run export TERM=xterm-256color in your remote session.
TypeError: Unsupported input type Non-primitive object (such as None or a list) passed to styling function. Ensure inputs are strings, numbers, or booleans.

🤝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository on GitHub.
  2. Create a branch:
    git checkout -b feature/my-feature
    
  3. Install development dependencies:
    pip install -e .[dev]
    
  4. Run the test suite:
    python -m unittest discover tests
    # or
    pytest
    
  5. Run the benchmark:
    python benchmarks/bench.py
    
  6. Commit & Push your changes, then submit a Pull Request.
🧪 Running Tests & Quality Checks Across Toolchains

Run the test suite using standard library unittest (zero third-party dependencies required):

python -m unittest discover tests

Or using pytest:

pytest -v

Lint with ruff and flake8:

ruff check .
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics

📷 Visual Assets Required

To complete the visual presentation in the README, please create and place the following image assets into docs/images/:

Image File Path Target Dimensions Description & Content to Show
docs/images/rcolor_banner.png 1280 x 400 px Centered project banner featuring modern typographic "Rcolor" logo with vibrant gradient glow on a sleek dark background (#0f172a).
docs/images/preview_foreground.png 800 x 480 px Terminal screenshot demonstrating 8 lines of text generated by Rcolor.foreground() showing diverse 256-color foregrounds.
docs/images/preview_rainbow.png 800 x 480 px Terminal screenshot demonstrating Rcolor.rainbow_fg() showing multi-line vibrant per-character rainbow text.
docs/images/preview_styles.png 800 x 480 px Terminal screenshot demonstrating foreground_background_style() showing bold, underline, and dual-tone color combinations.
docs/images/preview_gradient.png 800 x 480 px Terminal screenshot demonstrating gradient_fg() and gradient_rainbow() showing smooth continuous multi-stop gradients across text.

📄 License

This project is licensed under the terms of the MIT License.

Metadata

Release files for Rcolor 3.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for Rcolor 3.1.0
File Size Uploaded
rcolor-3.1.0.tar.gz 48.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for Rcolor 3.1.0
File Interpreter ABI Platform
rcolor-3.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 77.5 kB

Release files / rcolor-3.1.0.tar.gz

Download URL rcolor-3.1.0.tar.gz
Size 48.4 kB
Tags Source
SHA-256 checksum
How to use checksums
758c81b895c5bf49a40c9461efd5362c80718e9d00b22a00f5ca5963c6b69791
BLAKE2b-256 checksum
How to use checksums
628809fbdf4d02843499fd72f21d1d9a46fd7b61f925a88930a65c2930e0f74b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / rcolor-3.1.0-py3-none-any.whl

Download URL rcolor-3.1.0-py3-none-any.whl
Size 29.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
456c08aab0de2bf4ac53afe29ea1d44bb20fe87125fdd2a70bf7830ee424e396
BLAKE2b-256 checksum
How to use checksums
a1f5b2d4a8b62afb36deaff32b624fbbc729fe89dfcb52750a6613c4fffd33c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.1.0 This release

2 release files

3.0.1

2 release files

3.0.0

2 release files

2.0.3

2 release files

2.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page