
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
make-colors
Advanced tools
A simple, powerful, and cross-platform Python library for adding colors, styles, and rich markup support to your terminal output. Optimized for **Windows 10+**, Linux, and macOS.
A simple, powerful, and cross-platform Python library for adding colors, styles, rich markup support, and beautiful tables to your terminal output. Optimized for Windows 10+, Linux, and macOS.
[red]Error[/] or [bold white on red]CRITICAL[/]pip install make_colors
from make_colors import make_colors
# Simple colored text
print(make_colors("Hello World!", "red"))
# Text with background
print(make_colors("Important Message", "white", "red"))
# Using shortcuts
print(make_colors("Quick and easy", "r", "bl")) # red text, blue background
# Using underscore notation
print(make_colors("One-liner style", "green_yellow")) # green text on yellow background
# Rich markup
print(make_colors("[bold white on red] CRITICAL [/]"))
# Import all
from make_colors import *
print(bl("Im Blue"))
color = Colors('red', 'white')
print(color("White on Red"))
color = Color('white', 'red')
print(color("TEST"))
# Create beautiful tables
from make_colors.table import Table
table = Table(title="Server Status", title_style="bold cyan")
table.add_column("Service", style="bold")
table.add_column("Status", style="green")
table.add_column("Uptime", style="yellow")
table.add_row("Web Server", "✓ Running", "15d 6h")
table.add_row("Database", "✓ Running", "15d 6h")
table.add_row("Cache", "⚠ Warning", "2d 3h", style="yellow")
print(table.draw())
| Color Name | Shortcuts | Light Variant | Light Shortcut |
|---|---|---|---|
| black | b, bk | lightblack | lb |
| red | r, rd, re | lightred | lr |
| green | g, gr, ge | lightgreen | lg |
| yellow | y, ye, yl | lightyellow | ly |
| blue | bl | lightblue | lb |
| magenta | m, mg, ma | lightmagenta | lm |
| cyan | c, cy, cn | lightcyan | lc |
| white | w, wh, wi, wt | lightwhite | lw |
# Standard colors
print(make_colors("■ Black text", "black"))
print(make_colors("■ Red text", "red"))
print(make_colors("■ Green text", "green"))
print(make_colors("■ Yellow text", "yellow"))
print(make_colors("■ Blue text", "blue"))
print(make_colors("■ Magenta text", "magenta"))
print(make_colors("■ Cyan text", "cyan"))
print(make_colors("■ White text", "white"))
# Light variants
print(make_colors("■ Light Red", "lightred"))
print(make_colors("■ Light Green", "lightgreen"))
print(make_colors("■ Light Blue", "lightblue"))
print(make_colors("■ Light Yellow", "lightyellow"))
print(make_colors("Full color names", "red", "white"))
print(make_colors("Using shortcuts", "r", "w"))
print(make_colors("Mixed notation", "red", "w"))
# Using underscore separator
print(make_colors("Error occurred!", "red_white"))
print(make_colors("Success!", "green_black"))
print(make_colors("Warning!", "yellow_red"))
# Using dash separator
print(make_colors("Info message", "blue-white"))
print(make_colors("Debug info", "cyan-black"))
# Using comma separator
print(make_colors("Critical message", "white,blue"))
print(make_colors("Alert info", "w,r"))
# System status display
def show_status(service, status):
if status == "running":
return make_colors(f"[✓] {service}", "lightgreen", "black")
elif status == "stopped":
return make_colors(f"[✗] {service}", "lightred", "black")
else:
return make_colors(f"[?] {service}", "lightyellow", "black")
print(show_status("Web Server", "running"))
print(show_status("Database", "stopped"))
print(show_status("Cache", "unknown"))
# Log level formatting
def log_message(level, message):
colors = {
"ERROR": ("lightwhite", "red"),
"WARNING": ("black", "yellow"),
"INFO": ("lightblue", "black"),
"DEBUG": ("lightgrey", "black")
}
fg, bg = colors.get(level, ("white", "black"))
return f"{make_colors(f' {level} ', fg, bg)} {message}"
print(log_message("ERROR", "Connection failed"))
print(log_message("WARNING", "Deprecated method used"))
print(log_message("INFO", "Server started successfully"))
print(log_message("DEBUG", "Variable value: 42"))
print(make_colors("Bold text", "red", attrs=["bold"]))
print(make_colors("Underlined", "blue", attrs=["underline"]))
print(make_colors("Italic + Bold", "green", attrs=["italic", "bold"]))
import time
for i in range(0, 101, 20):
bar = "█" * (i // 5) + "░" * (20 - i // 5)
print(f"\r{make_colors(f'[{bar}] {i}%', 'yellow')}", end="")
time.sleep(0.2)
print()
def progress_bar(current, total, width=50):
percentage = current / total
filled = int(width * percentage)
bar = "█" * filled + "░" * (width - filled)
if percentage < 0.5:
color = "red"
elif percentage < 0.8:
color = "yellow"
else:
color = "green"
return make_colors(f"[{bar}] {current}/{total} ({percentage:.1%})", color)
# Simulate progress
for i in range(0, 101, 10):
print(f"\r{progress_bar(i, 100)}", end="", flush=True)
time.sleep(0.1)
print() # New line after completion
def create_menu():
options = [
("1", "Start Application", "green"),
("2", "Settings", "yellow"),
("3", "Help", "blue"),
("4", "Exit", "red")
]
print(make_colors(" 🎯 Main Menu ", "white", "blue"))
print()
for key, option, color in options:
print(f" {make_colors(key, 'white', color)} {option}")
print()
return input("Select option: ")
# Usage
choice = create_menu()
Create beautiful, colored tables with a Rich-style API!
from make_colors.table import Table
# Rich-style API
table = Table(title="[bold cyan]Package Info[/]", header_style="bold white")
table.add_column("Package", style="bold")
table.add_column("Version", style="green")
table.add_column("Status", style="yellow")
table.add_row("numpy", "1.21.0", "✓ OK")
table.add_row("pandas", "1.3.0", "⚠ Update", style="bold yellow")
table.add_row("requests", "2.26.0", "✓ OK")
print(table.draw())
add_column() and add_row()[color]text[/] in headers and cellsfrom make_colors.table import Table
# With title and styles
table = Table(
title="My Report",
title_style="bold cyan", # or "bold-cyan"
header_style="bold white", # or "bold-white"
max_width=80 # 0 for unlimited
)
# Add columns with styling
table.add_column("Name", style="bold", align="l")
table.add_column("Price", style="green", align="r", dtype="f")
table.add_column("Stock", style="cyan", align="r", dtype="i")
table.add_column("Status", style="yellow", align="c")
# Add rows with optional styling
table.add_row("Product A", 99.99, 150, "Available")
table.add_row("Product B", 149.99, 0, "Out of Stock", style="bold red")
table.add_row("Product C", 199.99, 75, "Low Stock", style="yellow")
# Set column properties
table.set_cols_align(["l", "r", "r", "c"])
table.set_cols_valign(["t", "m", "b", "t"])
table.set_cols_dtype(["t", "f", "i", "t"])
table.set_cols_width([20, 10, 10, 15])
# Set column colors (NEW!)
table.set_cols_color(["bold", "green", "cyan", "yellow"])
table.set_cols_color(["y", "r", "c", "g"]) # Using abbreviations
# Set row colors (NEW!)
table.set_rows_color(["green", "yellow", "bold-red", None])
# Set header
table.header(["Name", "Price", "Stock", "Status"])
# Add rows
table.add_row("Product A", 99.99, 150, "Available")
table.add_row("Product B", 149.99, 0, "Out of Stock")
Tables support Rich markup in headers, cells, and titles:
# Rich markup in title
table = Table(title="[bold cyan]Server Status[/]")
# Rich markup in column headers
table.add_column("[bold white]Service[/]")
table.add_column("[white on blue]Status[/]")
table.add_column("[white on green]Uptime[/]")
# Rich markup in cells
table.add_row("[bold]Web Server[/]", "✓ Running", "15d 6h")
from make_colors.table import Table
table = Table(title="Package Version Checker", title_style="bold cyan")
table.add_column("Package", style="bold")
table.add_column("Installed", style="cyan")
table.add_column("Required", style="magenta")
table.add_column("Status", style="yellow")
table.add_row("numpy", "1.21.0", "1.20.0", "✓ OK")
table.add_row("pandas", "1.3.0", "1.4.0", "⚠ Update", style="bold yellow")
table.add_row("requests", "2.26.0", "2.26.0", "✓ OK")
table.add_row("flask", "1.1.0", "2.0.0", "✗ Old", style="bold red")
print(table.draw())
table = Table()
table.set_cols_align(["l", "c", "r", "r"])
table.set_cols_color(["bold-white", "cyan", "yellow", "magenta"])
table.header(["Service", "Status", "CPU %", "Memory %"])
table.add_row("Web Server", "✓ Running", "45.2", "62.8")
table.add_row("Database", "✓ Running", "78.5", "85.3")
table.add_row("Cache", "⚠ Warning", "92.1", "95.7")
print(table.draw())
table = Table(title="Task Status", title_style="bold-cyan")
table.header(["Task", "Status", "Progress", "Priority"])
table.add_row("Deploy to Production", "✓ Complete", "100%", "High")
table.add_row("Code Review", "⚠ In Progress", "75%", "Medium")
table.add_row("Write Tests", "● Pending", "0%", "High")
table.add_row("Fix Bug #123", "✗ Blocked", "30%", "Critical")
# Color rows based on status
table.set_rows_color([
"bold-green", # Complete
"bold-yellow", # In Progress
"dim", # Pending
"bold-red" # Blocked
])
print(table.draw())
table = Table(title="[bold magenta]Sales Dashboard[/]")
table.add_column("[bold white]Product[/]", align="l")
table.add_column("[bold green]Revenue[/]", align="r", dtype="f")
table.add_column("[white on blue]Units Sold[/]", align="r", dtype="i")
table.add_column("[bold yellow on black]Trend[/]", align="c")
table.add_row("Widget A", 125000.50, 1234, "📈 Up")
table.add_row("Widget B", 89000.25, 890, "📉 Down", style="dim")
table.add_row("Widget C", 250000.00, 2500, "🔥 Hot", style="bold-green")
print(table.draw())
table = Table(title="User List", title_style="bold-cyan")
table.header(["ID", "Username", "Email", "Status"])
users = [
["001", "john_doe", "john@example.com", "Active"],
["002", "jane_smith", "jane@example.com", "Active"],
["003", "bob_wilson", "bob@example.com", "Inactive"],
["004", "alice_brown", "alice@example.com", "Active"],
["005", "charlie_davis", "charlie@example.com", "Active"],
]
for user in users:
table.add_row(*user)
# Alternate between dim and normal
table.set_rows_color(["dim", None, "dim", None, "dim"])
print(table.draw())
# Horizontal: "l" (left), "c" (center), "r" (right)
table.set_cols_align(["l", "c", "r"])
# Vertical: "t" (top), "m" (middle), "b" (bottom)
table.set_cols_valign(["t", "m", "b"])
# "a" (auto), "t" (text), "f" (float), "e" (exponential), "i" (integer)
table.set_cols_dtype(["t", "f", "i", "a"])
# Customize border characters
table.set_chars(['-', '|', '+', '=']) # [horiz, vert, corner, header]
# Control decorations
table.set_deco(Table.BORDER | Table.HEADER) # Border + header line only
table.set_deco(Table.VLINES | Table.HLINES) # Only lines, no border
All make_colors formats are supported:
# Full names
table.set_cols_color(["red", "green", "blue"])
# Abbreviations
table.set_cols_color(["r", "g", "bl"])
# With attributes
table.set_cols_color(["bold-red", "italic-cyan", "dim-yellow"])
# With background
table.set_cols_color(["white-red", "black-yellow", "green-black"])
# Mixed formats
table.set_cols_color(["bold-white", "r", "italic-cyan", "lb-b"])
| Variable | Values | Description |
|---|---|---|
MAKE_COLORS | 0 or 1 | Disable/enable colors globally |
MAKE_COLORS_FORCE | 0, 1, True | Force colors even when unsupported |
MAKE_COLORS_DEBUG | 1, true, True | Enable debug parsing logs |
Example:
import os
# Disable colors
os.environ['MAKE_COLORS'] = '0'
print(make_colors("No colors", "red")) # Output: "No colors" (no coloring)
# Force colors (useful for CI/CD or redirected output)
os.environ['MAKE_COLORS_FORCE'] = '1'
print(make_colors("Forced colors", "green")) # Always colored
make_colors(string, foreground='white', background=None, attrs=[], force=False)Main function to colorize strings with ANSI or Rich markup.
string (str) — Input text, supports Rich markup like [red]Error[/]foreground (str) — Foreground colorbackground (str|None) — Background colorattrs (list) — List of attributes: bold, underline, italic, etc.force (bool) — Force enable colorsReturns:
str (Colorized string with ANSI escape codes)make_color(...)Alias for make_colors.
print(string, ...)Convenience print wrapper that applies make_colors before printing.
parse_rich_markup(text)Parses strings like [bold red on black]Hello[/] into (content, fg, bg, style) tuples. Supports multiple tags.
getSort(data, foreground, background)Parses combined formats like red-yellow, g_b, expanding into (fg, bg).
color_map(code)Maps abbreviations like r, bl, lg to full names.
Examples:
# Basic usage
make_colors("Hello", "red")
# With background
make_colors("Hello", "white", "red")
# Using shortcuts
make_colors("Hello", "w", "r")
# Separator notation
make_colors("Hello", "white_red")
# Force colors
make_colors("Hello", "red", force=True)
MakeColors classcolored(string, fg, bg, attrs) → low-level ANSI outputrich_colored(string, color, bg, style) → Rich style supportsupports_color() → Detect terminal support, return: bool: True if colors are supported, False otherwisefrom make_colors import MakeColors
if MakeColors.supports_color():
print("Colors are supported!")
else:
print("Colors not supported on this terminal")
MakeColorsError — Raised when invalid colors are usedMakeColorsWarning — Non-critical fallback warningsThe library supports Rich-style markup similar to the rich package:
print(make_colors("[red]Error[/] [bold white on blue]CRITICAL[/] [green]OK[/]"))
Supported styles:
# Using console
from make_colors import Console
console = Console()
console.print("[white on red]This is Example ERROR ![/]")
def test_all_colors():
"""Test all available colors"""
colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
light_colors = [f'light{color}' for color in colors if color != 'black'] + ['lightgrey']
print("=== Standard Colors ===")
for color in colors:
print(make_colors(f" {color.ljust(10)}", color, "black"))
print("\n=== Light Colors ===")
for color in light_colors:
print(make_colors(f" {color.ljust(15)}", color, "black"))
# Run the test
test_all_colors()
from make_colors import MakeColors
print("Supports colors:", MakeColors.supports_color())
def test_all_colors():
"""Test all available colors"""
colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
light_colors = [f'light{color}' for color in colors if color != 'black'] + ['lightgrey']
print("=== Standard Colors ===")
for color in colors:
print(make_colors(f" {color.ljust(10)}", color, "black"))
print("\n=== Light Colors ===")
for color in light_colors:
print(make_colors(f" {color.ljust(15)}", color, "black"))
# Run the test
test_all_colors()
### Testing Tables
```python
from make_colors.table import Table
# Test basic table
table = Table()
table.header(["Column 1", "Column 2", "Column 3"])
table.add_row("Data 1", "Data 2", "Data 3")
print(table.draw())
# Test colored table
table = Table(title="Test Table", title_style="bold cyan")
table.add_column("Name", style="bold")
table.add_column("Value", style="green")
table.add_row("Test", "Success", style="green")
print(table.draw())
MakeColors.supports_color() before production usefrom make_colors import make_colors, MakeColors
def safe_print(text, fg="white", bg=None):
"""Safely print colored text with fallback"""
if MakeColors.supports_color():
print(make_colors(text, fg, bg))
else:
print(f"[{fg.upper()}] {text}")
# Usage
safe_print("This works everywhere!", "green")
from make_colors import *
print(red("Error!"))
print(bl("Im Blue"))
print(green_on_black("Success"))
# Abbreviation
print(w_bl("White on Blue")) # white on blue
print(r_w("Red on White")) # red on white
print(g_b("Green on Black")) # green on black
print(lb_b("Light Blue on Black"))
color = Colors('red', 'white')
print(color("White on Red"))
color = Color('white', 'red')
print(color("TEST"))
# Try and see what happened 👍 😄
MakeColorsError for invalid color names (if strict)MakeColorsWarning for warningstry:
print(make_colors("Oops", "notacolor"))
except Exception as e:
print("Handled:", e)
[red]text[/][white on red]text[/][bold green]text[/][bold white on red]ALERT[/][cyan]Info[/] [red]Error[/]table.add_column("Name", style="bold")table.add_column("[white on blue]Status[/]")table.set_cols_color(["r", "g", "b"])table.set_rows_color(["green", "yellow", "red"])table.add_row(..., style="bold red")PRs welcome! Open issues for feature requests or bugs. Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Licensed under the MIT License. See LICENSE.
Hadi Cahyadi 📧 cumulus13@gmail.com
✨ Made with ❤️ by Hadi Cahyadi for colorful terminal experiences!
FAQs
A simple, powerful, and cross-platform Python library for adding colors, styles, and rich markup support to your terminal output. Optimized for **Windows 10+**, Linux, and macOS.
We found that make-colors demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.