Skip to main content

Terminal string formatting with simple //color/ syntax. Zero dependencies.

Project description

English Português Español 中文

EasyAnsi

The easy and practical way to color terminal text.
Simple commands. No setup. Write color inside your strings like an f-string.
Zero dependencies · Fail-safe · Built for beginners and daily scripts.

PyPI version License MIT Python >= 3.8 Zero dependencies Typed


Overview

EasyAnsi is a lightweight Python library that turns plain strings into ANSI-colored terminal output using an intuitive markup syntax inspired by f-strings — not by Rich's bracket syntax.

Write color directly inside your strings:

from easyansi import eprint

quantity = 12
eprint(f"//bold-blue/All {quantity} cookies were sold today/bold-blue")
eprint(f"Only //red/{quantity}/red items left in stock")

No configuration. No heavy console object. No crash if a tag is misspelled — unknown names stay as plain text.


Behind the Project

I am learning Python. While studying, I noticed that coloring terminal text could be much simpler than what existing libraries offered — and that complexity was getting in the way of my own learning.

I have been an elementary school teacher for 14 years. In the classroom, I learned to spot what helps or hinders daily practice: clear instructions, easy-to-remember commands, and tools that do not punish mistakes. That is the lens through which I designed EasyAnsi — not as a programming expert, but as someone who cares about learning, teaching, and everyday practicality.

Transparency: this library was built with the support of artificial intelligence. I prefer to say that openly rather than pretend I master everything in this codebase. I am still building my technical skills in Python — and EasyAnsi is part of that journey.

What I genuinely bring is the experience of someone who teaches every day: noticing unnecessary barriers, simplifying the path, and thinking about those who are just starting out. EasyAnsi comes from that combination — the curiosity of a learner, the sensitivity of a teacher, and honesty about how it was made.

What 14 years in the classroom taught me about code

In the classroom In EasyAnsi
Mistakes must not block learning Unknown tags become plain text — the program never crashes
Short, clear instructions //color/ syntax as easy to remember as an f-string
See before you memorize preview() shows every color in your terminal
Ready-to-use daily tools success(), error(), setup_logging() — one command and done

Using AI does not make me an impostor: I am someone still learning who spotted a real need and chose an honest way to address it — with the same care I put into preparing a lesson to make my students' lives easier.


Our Goal: Easier and More Practical

EasyAnsi exists for one reason: make terminal colors accessible to everyone, not just experts.

What you want EasyAnsi Typical heavy libraries
Start in 30 seconds from easyansi import eprint Configure a Console, learn markup rules
Color one word //red/{value}/red inside f-string Wrap objects, build Text segments
Say "success" success("Done") Build custom renderables
Enable logging colors setup_logging() — one line Custom handlers, themes, plugins
Wrong tag name Stays as plain text (no crash) May raise markup errors

Philosophy: fewer concepts, fewer imports, commands you can remember and reuse every day.


Practical Commands (Cheat Sheet)

Copy and use — no extra setup required:

from easyansi import eprint, einput, fmt, success, error, warning, info, red, green, bold, ansi, title, paint

# Print with color (most common)
eprint("//green/Hello!/green")
eprint(f"Score: //bold-blue/{score}/bold-blue")

# Whole text at once (no inline tags)
print(ansi("Hello!").easyansi("bold-blue"))
print(paint("Hello!", "bold-blue"))

# Decorative title
print(ansi("STUDENT REGISTRATION").title("="))

# One-word shortcuts
print(red("error"), green("ok"), bold("title"))
print(bold(red("critical")))                  # chain shortcuts
print("//bg-yellow/warning on yellow/bg-yellow")  # with activate()

# Status lines (ready to go)
success("Saved")
error("Failed")
warning("Slow connection")
info("Port 8080")

# Input with colored prompt
name = einput("//cyan/Name/cyan: ")

# String only (no print)
text = fmt("//yellow/warning/yellow")

# See all colors in terminal
import easyansi; easyansi.preview()

Logging in one line:

from easyansi.logging import setup_logging
setup_logging()          # done — logging.info() is now colored

Features

Feature Description
Simple syntax //color/text/color — open with //name/, close with /name or //
Partial coloring Color one word inside an f-string without wrapping the whole line
Whole-text styling ansi("text").easyansi("bold-blue") or paint("text", "bold-blue")
Decorative titles title("Title", "=") or .title("=") with separate line/text colors
Styles + colors Combine with -: bold-blue, italic-underline-red
True colors Hex support: //#ff8800/orange/#ff8800
Backgrounds bg-blue, bg-#222222
Bilingual names English + Portuguese aliases (negrito, vermelho, …)
Direct shortcuts red(), bold(), green() — great for IDE autocomplete
Status helpers success(), error(), warning(), info()
Colored logging Drop-in ColorFormatter for Python's logging module
Fail-safe parser URLs like https:// and unknown tags never break output
Smart output Auto plain text when piped, redirected, or NO_COLOR is set
Windows ready VT/ANSI enabled automatically on import
Zero deps Stdlib only — installs anywhere

Requirements

  • Python 3.8+
  • A terminal that supports ANSI escape codes (enabled automatically on Windows 10+)

Installation

pip install py-easyansi

Import in code: from easyansi import eprint (PyPI name differs from the module name).

From source:

git clone https://github.com/GustaFranz/easyansi.git
cd easyansi
pip install -e ".[dev]"

Quick Start

Recommended — use normal print and input:

import easyansi

easyansi.activate()   # one line at the top of your script

print("//green/Everything OK!/green")
print(f"Stock: //red/{3}/red units remaining")
name = input("Enter //cyan/your name/cyan: ")

No need to rename functions. Call easyansi.deactivate() to restore the originals.

Alternative — explicit eprint / einput:

from easyansi import eprint, einput, fmt

eprint("//green/Everything OK!/green")
eprint("Stock: //red/3/red units remaining")
name = einput("Enter //cyan/your name/cyan: ")
message = fmt("//yellow/warning/yellow")

Syntax Guide

Opening and closing tags

Pattern Meaning Example
//name/ Open tag //red/
/name Close tag (explicit) /red
// Close last open tag //green/text//

Combine styles and colors

Use - to stack attributes (examples assume easyansi.activate() was called):

print("//bold-blue/header/bold-blue")
print("//italic-underline-magenta/highlight/italic-underline-magenta")
print("//bg-yellow/black text on yellow/bg-yellow")
print("//#ff8800/exact orange/#ff8800")

Works inside f-strings

value = 42
print(f"Result: //green/{value}/green points")

Escape literal slashes

print(r"path: \/usr\/local/bin")

Fail-safe by design

Only known style/color names are interpreted. Everything else stays literal:

print("Visit https://example.com/page")   # URL untouched
print("//typo/text/typo")                 # treated as plain text

Customization Examples

Everyday patterns you can copy and adapt (with activate()):

import easyansi
easyansi.activate()

# entire line
print("//green/Saved successfully/green")

# only one word
score = 10
print(f"Score: //bold-blue/{score}/bold-blue points")

# style + color combined
print("//italic-underline-magenta/Important note/italic-underline-magenta")

# background and hex
print("//bg-yellow/black on yellow/bg-yellow")
print("//#ff8800/custom orange/#ff8800")

# Portuguese aliases also work
print("//negrito-vermelho/Error/negrito-vermelho")

Whole Text & Decorative Titles

Color an entire string without inline tags, or build banner titles with repeated characters.

from easyansi import ansi, title, paint, ask, activate

activate()

# Color entire text for print
print(ansi("Hello, world!").easyansi("bold-blue"))
print(paint("Hello", "bold-blue"))

# Input scopes: prompt, answer, or both
nome = ansi("What is your name?").easyansi("bold-blue", scope="prompt").read()
nome = ansi("What is your name?").easyansi("green", scope="answer").read()
nome = ansi("What is your name?").easyansi("bold-blue", scope="both").read()
nome = ask("What is your name?", prompt_style="bold-blue", answer_style="green")

# Decorative titles
print(ansi("STUDENT REGISTRATION").title("="))
print(title("STUDENT REGISTRATION", "-", line_style="blue", text_style="bold"))
print(ansi("MENU").title("~", style="bold-blue"))

Scope (scope): text (default) · prompt · answer · both

Note: The terminal cannot color keystrokes in real time during input(). Coloring the answer applies ANSI to the returned string, so it appears colored when you print it later.


API Reference

Core functions

Function Description
activate() Makes global print and input interpret EasyAnsi markup
deactivate() Restores original print and input
is_active() Returns whether activate() is in effect
fmt(text, *, color=None) Returns formatted string (ANSI or plain)
eprint(*values, sep=" ", end="\n", file=None, color=None, flush=False) Colored print
einput(prompt="", *, color=None) Colored input (accepts str or AnsiText)
preview(file=None) Prints all available styles and colors
ansi(text) Fluent wrapper for whole-text styling and titles
title(text, char="=", ...) Decorative title with repeated lines
paint(text, style, *, color=None) Apply style to entire text (text first)
ask(text, *, prompt_style=None, answer_style=None) Colored input with scope helpers

color parameter: None = auto-detect terminal · True = force ANSI · False = plain text

Color shortcuts

black · red · green · yellow · blue · magenta · cyan · white

from easyansi import red, green, yellow, blue, magenta, cyan, white, black

print(red("error"), green("success"), yellow("warning"))
print(blue("info"), magenta("highlight"), cyan("prompt"), white("plain"))
print(black("dark text"))

Style shortcuts

bold · dim · italic · underline · strike · style(name, text)

from easyansi import bold, dim, italic, underline, strike, style, red

print(bold("title"), dim("secondary"), italic("note"))
print(underline("link"), strike("removed"))
print(bold(red("critical")))                 # chain shortcuts
print(style("bold-blue", "custom combo"))   # any name via style()

All shortcuts accept color=None|True|False.

Status messages

from easyansi import success, error, warning, info

success("Deploy completed")
error("Connection failed")
warning("Cache is stale")
info("Listening on port 8000")

Symbols fall back to ASCII ([OK], [ERRO]) when the terminal encoding cannot render Unicode.


Colored Logging

Integrates with Python's standard logging module. Log levels are colored in the terminal; output stays clean in files and when NO_COLOR is set.

import logging
from easyansi.logging import ColorFormatter, setup_logging

# Option 1 — attach to existing setup
handler = logging.StreamHandler()
handler.setFormatter(ColorFormatter())
logging.root.addHandler(handler)
logging.info("Server started")

# Option 2 — one-line setup
setup_logging(level=logging.INFO)
logging.warning("Cache outdated")
logging.error("Connection failed")

Default level colors:

Level Style
DEBUG dim
INFO cyan
WARNING yellow
ERROR red
CRITICAL bold-red

EasyAnsi markup in log messages:

setup_logging(markup=True, force=True)
logging.info("//green/Deploy completed/green")

Custom level colors (optional):

import logging
from easyansi.logging import ColorFormatter, setup_logging

handler = logging.StreamHandler()
handler.setFormatter(ColorFormatter(level_colors={
    logging.DEBUG: "dim",
    logging.INFO: "green",
    logging.WARNING: "yellow",
    logging.ERROR: "bold-red",
    logging.CRITICAL: "bold-red",
}))
logging.root.addHandler(handler)

ColorFormatter parameters: fmt, datefmt, color, markup, level_colors, stream


Style & Color Reference

Text styles

English Portuguese Tag Preview
Bold Negrito bold / negrito sample
Dim Fraco dim / fraco dim sample
Italic Itálico italic / italico sample
Underline Sublinhado underline / sublinhado sample
Strikethrough Tachado strike / tachado sample
print("//bold/Bold/bold  //dim/Dim/dim  //italic/Italic/italic")
print("//underline/Underline/underline  //strike/Strikethrough/strike")

Named colors

English Portuguese Tag Preview
Black Preto black / preto black black
Red Vermelho red / vermelho red red
Green Verde green / verde green green
Yellow Amarelo yellow / amarelo yellow yellow
Blue Azul blue / azul blue blue
Magenta Rosa magenta / rosa magenta magenta
Cyan Ciano cyan / ciano cyan cyan
White Branco white / branco white white
print("//red/red  //green/green  //yellow/yellow  //blue/blue")
print("//magenta/magenta  //cyan/cyan  //white/white  //black/black")

Variants

Variant Tag Preview
Bright bright-red, claro-vermelho bright bright
Background bg-blue, fundo-azul bg bg blue
True color (hex) #ff8800, bg-#222222 hex #ff8800 bg bg-#222222
print("//bright-red/bright/bright-red")
print("//bg-blue/blue background/bg-blue")
print("//bg-#222222/dark panel/bg-#222222")
print("//#ff8800/exact hex color/#ff8800")

Portuguese aliases

English tags and Portuguese aliases are interchangeable:

print("//negrito-vermelho/error/negrito-vermelho")
print("//fundo-amarelo/warning on yellow/fundo-amarelo")

Discover everything in your terminal

import easyansi
easyansi.preview()

Smart Output Behavior

EasyAnsi follows community conventions and behaves correctly in all environments:

Condition Behavior
Interactive terminal (TTY) ANSI colors applied
Piped / redirected output Plain text (no escape codes)
NO_COLOR env var set Plain text (no-color.org)
FORCE_COLOR env var set Colors forced on
TERM=dumb Plain text
Windows 10+ VT mode enabled on import

Manual override:

from easyansi import fmt

fmt("//red/error/red", color=True)   # always colored
fmt("//red/error/red", color=False)  # always plain — good for files/export

Architecture

Modular design with minimal coupling — each module has a single responsibility:

string → parser.parse → tokens → renderer.render → output
                  ↑                      ↑
              codes.py            terminal.py (TTY / NO_COLOR)
Module Role
codes.py ANSI code tables and name resolution
parser.py Markup tokenization (stack, nesting, escape)
renderer.py Token → ANSI string (or plain text)
terminal.py Environment detection, Windows VT
api.py fmt, eprint, einput
shortcuts.py Direct color/style functions and status helpers
logging.py ColorFormatter, setup_logging
preview.py Visual palette discovery

Development

pip install -e ".[dev]"
pytest

Run tests with the source layout:

PYTHONPATH=src pytest

Contributing

Contributions are welcome. Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new behavior
  4. Ensure pytest passes
  5. Open a pull request

Roadmap

  • Accessibility themes (high contrast palettes)
  • HTML / PDF export backends
  • Colored tracebacks in logging

License

MIT — see LICENSE.


Made with care for developers who want practical terminal color — easy commands, zero overhead.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_easyansi-0.5.0.tar.gz (51.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_easyansi-0.5.0-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

Details for the file py_easyansi-0.5.0.tar.gz.

File metadata

  • Download URL: py_easyansi-0.5.0.tar.gz
  • Upload date:
  • Size: 51.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for py_easyansi-0.5.0.tar.gz
Algorithm Hash digest
SHA256 5b04fb1f09ee756bdc68eafdf339dd8acc2256a75400624344b4ec1885385461
MD5 4a152d0d57a0ea96eec915ae894436fd
BLAKE2b-256 c6c7efb221e020d77091ead3e45b1116f3d64e7f2a889ad5a656b29ccbaec06b

See more details on using hashes here.

File details

Details for the file py_easyansi-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: py_easyansi-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 25.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for py_easyansi-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 239036e58dcc63ffde88846789abccbf7779fa8487000d53564d4a61f7daa280
MD5 d0859e7cfe59f3ec9439b5d239aa033b
BLAKE2b-256 4bd18e0fc76e9ddbaa51bfc0a8bd44f4cb6432ded3384fec5b9d586168587f91

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page