ASCIIColors šØ Rich Terminal Output Made Simple

One library. Colors. Logging. Progress. Menus. Prompts. Panels. Tables. Done.
Stop wrestling with multiple CLI libraries. ASCIIColors unifies everything you need for modern terminal applications into a single, elegant toolkit ā from quick colored output to production-grade logging, interactive menus, smart prompts, and rich UI components.
| 256-color support, bright variants, backgrounds, bold/italic/underline/blink | Full logging compatibility with handlers, formatters, JSON output, rotation | tqdm-like bars with custom styles (fill, blocks, line, emoji), thread-safe |
| Panels, tables, trees, syntax highlighting, live displays, markdown | Drop-in questionary replacement: text, password, confirm, select, checkbox, autocomplete | Spinners, syntax highlighting, enhanced tracebacks with locals, multicolor text, confirm/prompt helpers |
š¦ Installation
pip install ascii_colors
Optional dependencies:
pip install ascii_colors[wcwidth]
pip install ascii_colors[dev]
Requirements: Python 3.8+
š Quick Start
Choose Your API
ASCIIColors offers three complementary approaches that work seamlessly together:
| Direct Print | Immediate visual feedback, status messages, user interaction | ASCIIColors.green("text") |
| Logging System | Structured application logs, filtering, multiple outputs | import ascii_colors as logging |
| Rich Components | Beautiful UI: panels, tables, trees, syntax highlighting | ASCIIColors.panel() or ASCIIColors.rich_print() |
1. Direct Print ā Instant Visual Feedback
Perfect for CLI tools, status messages, and user-facing output:
from ascii_colors import ASCIIColors
ASCIIColors.red("Error: Connection failed")
ASCIIColors.green("ā Success!")
ASCIIColors.yellow("Warning: Low memory", style=ASCIIColors.style_bold)
ASCIIColors.blue("Info: Processing item 42")
ASCIIColors.print(
" CRITICAL ALERT ",
color=ASCIIColors.color_black,
background=ASCIIColors.color_bg_red,
style=ASCIIColors.style_bold + ASCIIColors.style_blink
)
ASCIIColors.rich_print("[bold red]Error:[/bold red] [yellow]Something went wrong[/yellow]")
2. Logging System ā Production-Grade Structured Logging
Full compatibility with Python's standard logging module:
import sys
import ascii_colors as logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)-8s] %(name)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
stream=sys.stdout
)
json_handler = logging.FileHandler("app.jsonl", mode='a')
json_handler.setFormatter(logging.JSONFormatter(
include_fields=["timestamp", "levelname", "name", "message", "pathname", "lineno"]
))
json_handler.setLevel(logging.WARNING)
logging.getLogger().addHandler(json_handler)
logger = logging.getLogger("MyService")
logger.info("Service started on port %d", 8080)
logger.warning("Disk usage at %d%%", 85)
logger.error("Failed to connect to database")
3. Rich Components ā Beautiful Terminal UI
Create stunning terminal interfaces with panels, tables, trees, and more:
from ascii_colors import ASCIIColors, rich
ASCIIColors.panel("Deployment successful!", title="ā Success", border_style="green")
ASCIIColors.table(
"Service", "Status", "Latency",
rows=[
["API Gateway", "[green]ā Healthy[/green]", "12ms"],
["Database", "[yellow]ā Degraded[/yellow]", "120ms"]
],
title="System Health"
)
root = ASCIIColors.tree("š project")
root.add("š src").add("š main.py")
root.add("š tests")
ASCIIColors.rich_print(root)
code = "def hello(): print('world')"
ASCIIColors.syntax(code, language="python", line_numbers=True)
with ASCIIColors.live("Starting...") as live:
for i in range(10):
live.update(f"Progress: {i+1}/10")
time.sleep(0.5)
⨠Complete Feature Guide
šØ Colors & Styles
Direct Color Methods
from ascii_colors import ASCIIColors
ASCIIColors.black("Black text")
ASCIIColors.red("Red text")
ASCIIColors.green("Green text")
ASCIIColors.yellow("Yellow text")
ASCIIColors.blue("Blue text")
ASCIIColors.magenta("Magenta text")
ASCIIColors.cyan("Cyan text")
ASCIIColors.white("White text")
ASCIIColors.orange("Orange text (256-color)")
ASCIIColors.bold("Bold text")
ASCIIColors.dim("Dim text")
ASCIIColors.italic("Italic text")
ASCIIColors.underline("Underlined text")
ASCIIColors.blink("Blinking text")
ASCIIColors.reverse("Reversed video")
ASCIIColors.hidden("Hidden text (password mask)")
ASCIIColors.strikethrough("Strikethrough text")
ASCIIColors.print(
"Complex styling",
color=ASCIIColors.color_cyan,
background=ASCIIColors.color_bg_black,
style=ASCIIColors.style_bold + ASCIIColors.style_italic
)
Rich Markup Syntax
Use Rich-style markup for inline styling anywhere:
from ascii_colors import ASCIIColors
ASCIIColors.rich_print("[red]Error[/red] [green]Success[/green] [blue]Info[/blue]")
ASCIIColors.rich_print("[yellow]Warning[/yellow] [magenta]Accent[/magenta] [cyan]Highlight[/cyan]")
ASCIIColors.rich_print("[bold]Bold[/bold] [italic]Italic[/italic] [underline]Underlined[/underline]")
ASCIIColors.rich_print("[dim]Dimmed[/dim] [blink]Blink[/blink]")
ASCIIColors.rich_print("[bright_red]Bright red[/bright_red] [bright_green]Bright green[/bright_green]")
ASCIIColors.rich_print("[on red]White on red[/on red]")
ASCIIColors.rich_print("[bold white on blue]Bold white on blue[/bold white on blue]")
ASCIIColors.rich_print("[success]Operation completed[/success]")
ASCIIColors.rich_print("[error]An error occurred[/error]")
ASCIIColors.rich_print("[warning]Warning message[/warning]")
ASCIIColors.rich_print("[info]Information[/info]")
ASCIIColors.rich_print("[danger]Critical issue[/danger]")
ASCIIColors.rich_print("[bold green]Hello World[/bold green]")
š„ļø Rich Components (UI Elements)
ASCIIColors includes a complete Rich-compatible rendering layer ā no external dependencies needed!
Panels
from ascii_colors import ASCIIColors
ASCIIColors.panel("Hello, World!", title="Greeting")
ASCIIColors.panel(
"[bold red]This is a warning message with important information.[/bold red]",
title="[bold yellow]ā Warning[/bold yellow]",
border_style="bold yellow",
box="round",
padding=(1, 2)
)
from ascii_colors import Panel, BoxStyle
panel = Panel(
"Content with [bold]markup[/bold] support",
title="[bold]Title[/bold]",
border_style="bold cyan",
box=BoxStyle.ROUND,
padding=(2, 4),
width=60
)
ASCIIColors.rich_print(panel)
Tables
from ascii_colors import ASCIIColors
ASCIIColors.table(
"Name", "Role", "Status",
rows=[
["Alice", "Admin", "[green]Active[/green]"],
["Bob", "User", "[green]Active[/green]"],
["Carol", "Guest", "[yellow]Pending[/yellow]"]
]
)
ASCIIColors.table(
"Package", "Version", "Status",
rows=[
["numpy", "1.24.0", "[green]ā up to date[/green]"],
["pandas", "2.0.0", "[yellow]ā update available[/yellow]"],
["requests", "2.28.0", "[red]ā security fix needed[/red]"]
],
title="[bold]Installed Packages[/bold]",
header_style="bold cyan",
show_lines=True,
box="round"
)
Trees
from ascii_colors import ASCIIColors
root = ASCIIColors.tree("š project", style="bold")
src = root.add_node("š src")
src.add("š __init__.py")
src.add("š main.py")
utils = src.add_node("š utils")
utils.add("š helpers.py")
tests = root.add_node("š tests")
tests.add("š test_main.py")
root.add("š README.md")
root.add("š pyproject.toml")
ASCIIColors.rich_print(root)
Syntax Highlighting
from ascii_colors import ASCIIColors
python_code = '''
def fibonacci(n):
"""Generate Fibonacci sequence."""
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
'''
ASCIIColors.syntax(python_code, language="python", line_numbers=True)
json_code = '''{
"name": "ascii_colors",
"version": "1.0.0",
"features": ["colors", "logging", "progress", "panels"]
}'''
ASCIIColors.syntax(json_code, language="json")
Markdown Rendering
from ascii_colors import ASCIIColors
markdown_text = """# ASCII Colors
A **powerful** library for terminal output.
## Features
- *Colors* and styles
- **Bold** and __underlined__ text
- `inline code` support
> This is a blockquote with important information.
| Feature | Status |
|---------|--------|
| Panels | ā |
| Tables | ā |
| Trees | ā |
"""
ASCIIColors.markdown(markdown_text)
Columns Layout
from ascii_colors import ASCIIColors
items = [
"Feature 1: Colors",
"Feature 2: Styles",
"Feature 3: Panels",
"Feature 4: Tables",
"Feature 5: Trees",
"Feature 6: Syntax"
]
ASCIIColors.columns(*items, equal=True, width=30)
Rules (Dividers)
from ascii_colors import ASCIIColors
ASCIIColors.rule()
ASCIIColors.rule("Section Title", style="cyan")
ASCIIColors.rule("Centered", style="bold magenta")
ASCIIColors.rule("Left", align="left", style="yellow")
ASCIIColors.rule("Right", align="right", style="green")
ASCIIColors.rule("Double", characters="ā", style="blue")
Live Displays
from ascii_colors import ASCIIColors
from ascii_colors import Text
import time
with ASCIIColors.live("Starting...", refresh_per_second=4) as live:
for i in range(10):
time.sleep(0.5)
bar = "ā" * (i + 1) + "ā" * (9 - i)
live.update(Text(f"Progress: [{bar}] {i+1}/10"))
time.sleep(0.3)
live.update(Text("[bold green]ā Complete![/bold green]"))
Status Spinners
from ascii_colors import ASCIIColors
import time
with ASCIIColors.status("Loading data...") as status:
time.sleep(3)
spinners = ["dots", "line", "arrow", "pulse", "star", "moon"]
for spinner in spinners:
with ASCIIColors.status(
f"Testing {spinner}...",
spinner=spinner,
spinner_style="cyan"
) as status:
time.sleep(2)
with ASCIIColors.status("Connecting...") as status:
time.sleep(1)
status.update("Authenticating...")
time.sleep(1)
status.update("Fetching data...")
š Advanced Rich Patterns
Combining Live with Panels and Tables
Create professional dashboards that update in real-time:
from ascii_colors import ASCIIColors
from ascii_colors import Panel, Table, Text, Columns
import time
import random
def create_dashboard(status, progress, logs):
"""Build a multi-panel dashboard layout."""
status_panel = Panel(
f"[bold cyan]{status}[/bold cyan]",
title="[bold]System Status[/bold]",
border_style="green" if "healthy" in status.lower() else "yellow",
width=40
)
bar = "ā" * (progress // 5) + "ā" * (20 - progress // 5)
progress_panel = Panel(
f"[bold]{bar}[/bold] {progress}%",
title="[bold]Progress[/bold]",
border_style="cyan",
width=40
)
log_text = "\n".join([f"[dim]{i+1}.[/dim] {log}" for i, log in enumerate(logs[-5:])])
logs_panel = Panel(
log_text or "[dim]No recent activity...[/dim]",
title="[bold]Recent Logs[/bold]",
border_style="magenta",
height=10
)
metrics = Table("Metric", "Value", "Trend", box="minimal")
metrics.add_row("CPU", f"{random.randint(20,80)}%", "[green]ā¼[/green]" if random.random() > 0.5 else "[red]ā²[/red]")
metrics.add_row("Memory", f"{random.randint(40,90)}%", "[green]ā¼[/green]" if random.random() > 0.5 else "[red]ā²[/red]")
metrics.add_row("Disk", f"{random.randint(50,95)}%", "[yellow]ā[/yellow]")
top_row = Columns([status_panel, progress_panel], equal=True)
return Text.assemble(
top_row, "\n",
logs_panel, "\n",
metrics
)
logs = []
with ASCIIColors.live(create_dashboard("Initializing...", 0, logs), refresh_per_second=4) as live:
for i in range(101):
if i % 10 == 0:
logs.append(f"Completed milestone {i//10}")
status = "Healthy" if i < 80 else "Degraded" if i < 95 else "Critical"
dashboard = create_dashboard(status, i, logs)
live.update(dashboard)
time.sleep(0.05)
logs.append("Process completed successfully")
live.update(create_dashboard("Complete", 100, logs))
time.sleep(1)
Nested Live Updates with Tables Inside Panels
from ascii_colors import ASCIIColors
from ascii_colors import Panel, Table, Text, Tree
import time
files = ["data_001.csv", "data_002.csv", "data_003.csv", "report.pdf", "summary.json"]
with ASCIIColors.live("Preparing...", refresh_per_second=2) as live:
for i, filename in enumerate(files):
table = Table("File", "Status", "Progress", "Size")
for j, f in enumerate(files):
if j < i:
status = "[green]ā Complete[/green]"
progress = "[green]100%[/green]"
size = f"{random.randint(100, 5000)} KB"
elif j == i:
status = "[yellow]ā³ Processing...[/yellow]"
prog_val = random.randint(10, 90)
bar = "ā" * (prog_val // 10) + "ā" * (10 - prog_val // 10)
progress = f"[yellow]{bar} {prog_val}%[/yellow]"
size = "..."
else:
status = "[dim]āø Pending[/dim]"
progress = "[dim]0%[/dim]"
size = "-"
table.add_row(f, status, progress, size)
panel = Panel(
table,
title=f"[bold]Batch Processing ({i+1}/{len(files)})[/bold]",
border_style="cyan"
)
live.update(panel)
time.sleep(1.5)
final_table = Table("File", "Status", "Size")
for f in files:
final_table.add_row(f, "[green]ā Complete[/green]", f"{random.randint(100, 5000)} KB")
success_panel = Panel(
final_table,
title="[bold green]ā All Files Processed[/bold green]",
border_style="green"
)
live.update(success_panel)
time.sleep(2)
Custom Console Instances
Create multiple consoles with different configurations:
from ascii_colors import ASCOIIColors
from ascii_colors import Console, Panel, Table
main_console = Console()
compact_console = Console(width=50, no_color=False)
log_console = Console(record=True)
main_console.print(Panel("Main Application", title="App"))
compact_console.print(Panel("Side Info", title="Compact"))
log_console.log("Event 1")
log_console.log("Event 2")
log_content = log_console.export_text()
jupyter_console = Console(force_jupyter=True)
jupyter_console.print("[blue]Notebook output[/blue]")
Status Spinner with Nested Live Display
Combine background status with foreground live updates:
from ascii_colors import ASCIIColors
from ascii_colors import Text
import time
with ASCIIColors.status("Analyzing dataset...", spinner="dots") as status:
time.sleep(2)
status.update("Loading data into memory...")
with ASCIIColors.live(Text("[dim]Preparing analysis...[/dim]"), refresh_per_second=2) as live:
for phase, duration in [("Cleaning", 2), ("Transforming", 3), ("Computing", 4)]:
for i in range(duration * 2):
progress = (i / (duration * 2)) * 100
bar = "ā" * int(progress / 5) + "ā" * (20 - int(progress / 5))
live.update(Text(
f"[bold cyan]{phase}:[/bold cyan] [{bar}] {progress:.0f}%\n"
f"[dim]Processing records...[/dim]"
))
time.sleep(0.5)
status.update(f"Completed {phase.lower()}")
live.update(Text("[bold green]ā Analysis Complete[/bold green]"))
time.sleep(1)
status.update("Saving results...")
time.sleep(1)
Rich Print with Conditional Formatting
from ascii_colors import ASCIIColors
responses = [
{"status": 200, "time": 45},
{"status": 404, "time": 120},
{"status": 500, "time": 30},
{"status": 200, "time": 25},
]
for resp in responses:
color = "green" if resp["status"] == 200 else "yellow" if resp["status"] < 500 else "red"
status_icon = "ā" if resp["status"] == 200 else "ā " if resp["status"] < 500 else "ā"
ASCIIColors.rich_print(
f"[{color}]{status_icon}[/{color}] "
f"Status: [bold]{resp['status']}[/bold] "
f"([{color}]{resp['time']}ms[/{color}])"
)
Panel with Internal Table and Tree
from ascii_colors import ASCIIColors
from ascii_colors import Panel, Table, Tree
tree = Tree("[bold]Project Structure[/bold]")
src = tree.add_node("[blue]src/[/blue]")
src.add("[green]__init__.py[/green]")
src.add("[green]main.py[/green]")
tests = tree.add_node("[blue]tests/[/blue]")
tests.add("[green]test_main.py[/green]")
stats_table = Table("Metric", "Value", box="minimal")
stats_table.add_row("Files", "12")
stats_table.add_row("Lines", "1,247")
stats_table.add_row("Coverage", "[green]87%[/green]")
combined_content = f"{tree}\n\n{stats_table}"
dashboard_panel = Panel(
combined_content,
title="[bold cyan]š Project Dashboard[/bold cyan]",
border_style="cyan",
padding=(1, 2)
)
ASCIIColors.rich_print(dashboard_panel)
šŖµ Logging System
Basic Configuration
import sys
import ascii_colors as logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)-8s] %(name)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger("MyApp")
console = logging.ConsoleHandler(stream=sys.stdout, level=logging.INFO)
console.setFormatter(logging.Formatter(
"{level_name:>8} | {message}",
style='{'
))
file_handler = logging.FileHandler("debug.log", level=logging.DEBUG)
file_handler.setFormatter(logging.Formatter(
"%(asctime)s | %(levelname)-8s | %(name)s:%(funcName)s:%(lineno)d | %(message)s",
include_source=True
))
json_handler = logging.FileHandler("events.jsonl", level=logging.WARNING)
json_handler.setFormatter(logging.JSONFormatter(
include_fields=["timestamp", "levelname", "name", "message", "pathname", "lineno"]
))
logging.getLogger().addHandler(console)
logging.getLogger().addHandler(file_handler)
logging.getLogger().addHandler(json_handler)
logger.debug("Debug info")
logger.info("Service started")
logger.warning("Disk full")
logger.error("Database error")
Contextual Logging
from ascii_colors import ASCIIColors, logging
ASCIIColors.set_context(
app_name="MyService",
app_version="1.2.3",
environment="production"
)
with ASCIIColors.context(
request_id="req-abc-123",
user_id="user-456"
):
logger.info("Processing request")
logger.info("Done")
logger.info("Cleanup")
š Progress Bars
from ascii_colors import ProgressBar, ASCIIColors
import time
for item in ProgressBar(range(100), desc="Processing"):
time.sleep(0.01)
for item in ProgressBar(
range(1000),
desc="Uploading",
color=ASCIIColors.color_cyan,
bar_style="fill",
progress_char="ā",
empty_char="ā"
):
process(item)
for item in ProgressBar(
range(100),
desc="Building",
bar_style="emoji",
progress_char="š",
empty_char="ā¬"
):
build_step()
with ProgressBar(total=1024*1024, desc="Uploading", unit="B") as pbar:
while chunk := read_chunk():
pbar.update(len(chunk))
from ascii_colors import Menu, ASCIIColors
menu = Menu("Choose format", mode='return')
menu.add_choice("JSON", value="json")
menu.add_choice("YAML", value="yaml")
menu.add_choice("XML", value="xml")
format_choice = menu.run()
def show_status():
ASCIIColors.green("All systems operational")
menu = Menu("System Manager", mode='execute')
menu.add_action("Show Status", show_status)
menu.add_action("Restart", restart_service)
menu.run()
menu = Menu("Select features", mode='checkbox')
menu.add_checkbox("Auth", value="auth", checked=True)
menu.add_checkbox("Cache", value="cache")
selected = menu.run()
menu = Menu("Select user", mode='return', enable_filtering=True)
menu.add_choices([
("Alice Anderson", "alice"),
("Bob Baker", "bob"),
("Charlie Chen", "charlie"),
])
ā Smart Prompts (Questionary-Compatible)
Complete drop-in replacement for the questionary library:
from ascii_colors import questionary
name = questionary.text("What's your name?", default="Anonymous").ask()
password = questionary.password(
"Set password",
confirm=True
).ask()
if questionary.confirm("Continue?", default=True).ask():
proceed()
color = questionary.select(
"Favorite color?",
choices=["Red", "Green", "Blue"]
).ask()
format_choice = questionary.select(
"Export format",
choices=[
{"name": "JSON (recommended)", "value": "json"},
{"name": "YAML", "value": "yaml", "disabled": True},
{"name": "CSV", "value": "csv"}
]
).ask()
features = questionary.checkbox(
"Select features",
choices=[
{"name": "Authentication", "value": "auth", "checked": True},
{"name": "Logging", "value": "logging"},
{"name": "Caching", "value": "cache"}
]
).ask()
city = questionary.autocomplete(
"Enter city",
choices=["New York", "London", "Tokyo", "Paris"],
ignore_case=True,
match_middle=True
).ask()
answers = questionary.form(
questionary.text("First name"),
questionary.text("Last name"),
questionary.confirm("Subscribe?", default=False)
).ask()
from ascii_colors.questionary import Validator, ValidationError
class EmailValidator(Validator):
def validate(self, document):
if "@" not in document:
raise ValidationError("Email must contain @")
email = questionary.text("Email:", validate=EmailValidator()).ask()
is_company = questionary.confirm("Company account?").ask()
company_name = questionary.text("Company name").skip_if(
not is_company, default="N/A"
).ask()
š ļø Utility Functions
from ascii_colors import ASCIIColors, get_trace_exception
def long_task():
time.sleep(3)
return "result"
result = ASCIIColors.execute_with_animation(
"Processing...",
long_task,
color=ASCIIColors.color_yellow
)
try:
risky_operation()
except Exception as e:
formatted = get_trace_exception(e, enhanced=True)
print(formatted)
ASCIIColors.trace_exception(e, enhanced=True)
ASCIIColors.multicolor(
["Status: ", "ACTIVE", " | Load: ", "85%"],
[
ASCIIColors.color_white,
ASCIIColors.color_green,
ASCIIColors.color_white,
ASCIIColors.color_yellow
]
)
ASCIIColors.highlight(
"ERROR: File not found",
subtext=["ERROR", "not found"],
highlight_color=ASCIIColors.color_bright_red
)
šØ Complete Color & Style Reference
Reset
color_reset | Reset all colors and styles |
Text Styles
style_bold | \u001b[1m | Bold/Bright |
style_dim | \u001b[2m | Dim/Faint |
style_italic | \u001b[3m | Italic |
style_underline | \u001b[4m | Underline |
style_blink | \u001b[5m | Slow blink |
style_blink_fast | \u001b[6m | Rapid blink |
style_reverse | \u001b[7m | Reverse video |
style_hidden | \u001b[8m | Hidden/Concealed |
style_strikethrough | \u001b[9m | Strikethrough |
Foreground Colors
color_black | 30 | color_bright_black | 90 |
color_red | 31 | color_bright_red | 91 |
color_green | 32 | color_bright_green | 92 |
color_yellow | 33 | color_bright_yellow | 93 |
color_blue | 34 | color_bright_blue | 94 |
color_magenta | 35 | color_bright_magenta | 95 |
color_cyan | 36 | color_bright_cyan | 96 |
color_white | 37 | color_bright_white | 97 |
color_orange | 38;5;208 | ā | ā |
Background Colors
color_bg_black | 40 | color_bg_bright_black | 100 |
color_bg_red | 41 | color_bg_bright_red | 101 |
color_bg_green | 42 | color_bg_bright_green | 102 |
color_bg_yellow | 43 | color_bg_bright_yellow | 103 |
color_bg_blue | 44 | color_bg_bright_blue | 104 |
color_bg_magenta | 45 | color_bg_bright_magenta | 105 |
color_bg_cyan | 46 | color_bg_bright_cyan | 106 |
color_bg_white | 47 | color_bg_bright_white | 107 |
color_bg_orange | 48;5;208 | ā | ā |
š Migration Guides
From Standard logging Module
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("myapp")
import ascii_colors as logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("myapp")
From colorama
from colorama import init, Fore, Back, Style
init()
print(Fore.RED + "Error" + Style.RESET_ALL)
from ascii_colors import ASCIIColors
ASCIIColors.red("Error")
From tqdm
from tqdm import tqdm
for i in tqdm(range(100)):
pass
from ascii_colors import ProgressBar
for i in ProgressBar(range(100), color=ASCIIColors.color_cyan):
pass
From questionary
import questionary
name = questionary.text("Name?").ask()
from ascii_colors import questionary
name = questionary.text("Name?").ask()
From rich
from rich import print
from rich.panel import Panel
from rich.table import Table
print(Panel("Hello"))
from ascii_colors import rich
ASCIIColors.rich_print(rich.Panel("Hello"))
from ascii_colors import ASCIIColors
ASCIIColors.panel("Hello")
š Documentation & Resources
š¤ Contributing
We welcome contributions! Please see CONTRIBUTING.md for:
- Development setup instructions
- Code style guidelines (we use Black)
- Testing requirements
- Pull request process
Quick start for contributors:
git clone https://github.com/ParisNeo/ascii_colors.git
cd ascii_colors
pip install -e ".[dev]"
pytest tests/
š Troubleshooting
Colors not showing in Windows
- Windows 10 version 1511+ supports ANSI colors natively
- For older systems, use Windows Terminal or VS Code terminal
- Legacy CMD may need
colorama: pip install colorama
Progress bar width issues with wide characters
pip install wcwidth
Logging not appearing
- Check global level:
ASCIIColors.set_log_level(LogLevel.DEBUG)
- Check handler level:
handler.setLevel(LogLevel.DEBUG)
- Ensure handler is added:
ASCIIColors.add_handler(handler)
š License
Apache License 2.0 ā see LICENSE for full details.
Ready to make your CLI applications shine?
pip install ascii_colors
Start building beautiful, powerful terminal applications today! š