Skip to main content

ascii-art

Tests Python License Type Checked Code Style Version

Programmatic ASCII art generation for TUI applications. Build text banners, convert images, draw shapes, render tables and charts, animate sprites — all as plain text strings ready for terminal display.

Installation

pip install ascii-art

With optional integrations:

pip install ascii-art[rich]      # Rich panels & text objects
pip install ascii-art[textual]   # Textual Static widgets
pip install ascii-art[dev]       # pytest, mypy, ruff

Quick Start

import ascii_art

# Figlet text banner
print(ascii_art.text_render("Hello!", font="slant"))

# Image to ASCII
print(ascii_art.image_render("photo.png", width=60))

# Draw shapes on a canvas
canvas = ascii_art.Canvas(40, 20)
ascii_art.circle(canvas, 20, 10, 8, char="*")
ascii_art.rectangle(canvas, 5, 3, 30, 14, char="#")
print(canvas.render())

# Border frame
print(ascii_art.frame("Important message", style=ascii_art.BorderStyle.ROUNDED, title="Notice"))

# Table
print(ascii_art.table(
    [["Alice", "92"], ["Bob", "87"]],
    headers=["Name", "Score"],
    style=ascii_art.BorderStyle.DOUBLE,
))

# Sparkline chart
print(ascii_art.sparkline([1, 4, 2, 8, 5, 7, 3, 6]))

# Bar chart
print(ascii_art.bar_chart([30, 80, 45, 60], labels=["Q1", "Q2", "Q3", "Q4"], width=30))

# Scatter plot
print(ascii_art.scatter([(1, 2), (3, 7), (5, 4), (8, 9)], width=40, height=15))

Fluent Builder API

Every module provides a Builder class for method-chaining style configuration:

from ascii_art import TextBuilder, BorderBuilder, ShapesBuilder, ChartBuilder

# Text
output = TextBuilder().text("Welcome").font("big").width(100).render()

# Borders
box = BorderBuilder().text("Hello").style(BorderStyle.DOUBLE).title("Greeting").render()

# Shapes — compose multiple primitives
scene = (
    ShapesBuilder()
    .width(60).height(20).char("*")
    .add_circle(30, 10, 8)
    .add_rectangle(5, 3, 50, 14)
    .add_line(0, 0, 59, 19)
    .render()
)

# Charts
chart = ChartBuilder().chart_type("bar").data([10, 20, 30]).width(50).labels(["A", "B", "C"]).render()

Text Rendering

Renders text using pyfiglet fonts with alignment control.

from ascii_art import text_render, list_fonts, Alignment

# List available curated fonts
print(list_fonts())
# ['banner', 'big', 'block', 'bubble', 'digital', 'lean', 'slant', 'small', 'standard', ...]

# Centered text
print(text_render("Title", font="shadow", width=60, align=Alignment.CENTER))

Image Conversion

Converts images to ASCII art using luminance mapping with optional edge detection.

from ascii_art import image_render, DETAILED_CHAR_RAMP, BLOCK_CHAR_RAMP

# Basic conversion
print(image_render("landscape.jpg", width=100))

# Inverted with detailed character set
print(image_render("logo.png", width=60, charset=DETAILED_CHAR_RAMP, invert=True))

# Edge detection (Sobel filter)
print(image_render("diagram.png", width=80, edges=True))

# From a PIL Image object
from PIL import Image
img = Image.open("photo.jpg")
print(image_render(img, width=120))

Three built-in character ramps are available:

Ramp Characters Use case
DEFAULT_CHAR_RAMP .:-=+*#%@ General purpose
DETAILED_CHAR_RAMP 70 chars, fine gradation High detail
BLOCK_CHAR_RAMP ░▒▓█ Block-style output

Shape Drawing

Draw primitives on a Canvas — a 2D character grid. All drawing functions mutate the canvas in-place and return it for chaining.

from ascii_art import Canvas, line, rectangle, circle, ellipse, triangle, diamond, arrow

c = Canvas(60, 25)
rectangle(c, 0, 0, 59, 24, "#")       # border
circle(c, 30, 12, 10, "o")            # centered circle
line(c, 0, 0, 59, 24, ".")            # diagonal
diamond(c, 30, 12, 5, "+")            # diamond overlay
triangle(c, 10, 20, 30, 5, 50, 20)    # triangle
arrow(c, 5, 12, 25, 12)               # horizontal arrow

print(c.render())

Canvases support overlay for compositing:

bg = Canvas(40, 20)
fg = Canvas(10, 5)
circle(fg, 5, 2, 2, "*")
bg.overlay(fg, 15, 7)  # paste fg onto bg at offset (15, 7)

Borders & Frames

from ascii_art import frame, divider, BorderStyle

# Six border styles: SINGLE, DOUBLE, ROUNDED, BOLD, ASCII, DASHED, SHADOW
print(frame("Content here", style=BorderStyle.ROUNDED, padding=2, title="Header"))

# Horizontal dividers
print(divider("Section", width=60, style=BorderStyle.DOUBLE))
# ═══════════════════════════ Section ══════════════════════════

Border Styles

SINGLE:  ┌──┐    DOUBLE:  ╔══╗    ROUNDED: ╭──╮
         │  │             ║  ║             │  │
         └──┘             ╚══╝             ╰──╯

BOLD:    ┏━━┓    ASCII:   +--+    DASHED:  ┌╌╌┐
         ┃  ┃             |  |             ╎  ╎
         ┗━━┛             +--+             └╌╌┘

SHADOW:  ┌──┐░
         │  │░
         └──┘░
          ░░░░

Tables

from ascii_art import table, Alignment, BorderStyle

data = [
    ["Alice", "Engineering", "92"],
    ["Bob", "Marketing", "87"],
    ["Carol", "Engineering", "95"],
]

print(table(
    data,
    headers=["Name", "Dept", "Score"],
    style=BorderStyle.BOLD,
    alignments=[Alignment.LEFT, Alignment.LEFT, Alignment.RIGHT],
))

Output:

┏━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━┓
┃ Name  ┃ Dept        ┃ Score ┃
┣━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━┫
┃ Alice ┃ Engineering ┃    92 ┃
┃ Bob   ┃ Marketing   ┃    87 ┃
┃ Carol ┃ Engineering ┃    95 ┃
┗━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━┛

Charts

from ascii_art import sparkline, bar_chart, scatter

# Sparkline — single-line Unicode block chart
print(sparkline([1, 4, 2, 8, 5, 7, 3, 6]))
# ▁▅▂█▄▆▃▅

# Horizontal bar chart with labels
print(bar_chart([30, 80, 45, 60], labels=["Q1", "Q2", "Q3", "Q4"], width=30))

# Scatter plot
print(scatter([(1, 1), (2, 4), (3, 2), (5, 8), (7, 3)], width=40, height=15))

Sprites & Animation

from ascii_art import Sprite, Animation, SPRITES

# Use a built-in sprite
heart = Sprite(SPRITES["heart"])
print(heart.render())

# Transforms (all return new Sprite)
flipped = heart.flip_h()
big = heart.scale(2)
rotated = heart.rotate(90)

# Animation from frames
frames = [heart, heart.flip_h(), heart.flip_v()]
anim = Animation(frames)
for frame in anim:
    print(frame.render())
    print("---")

Built-in sprites: heart, star, arrow_right, smiley.

Framework Integrations

Rich

from ascii_art.integrations.rich_panel import to_text, to_panel
from rich.console import Console

console = Console()
art = ascii_art.text_render("Hello", font="slant")
console.print(to_panel(art, title="ASCII Art"))

Textual

from ascii_art.integrations.textual_widget import to_static

widget = to_static(ascii_art.text_render("Dashboard"))
# Use in a Textual app's compose() method

Curses

from ascii_art.integrations.curses_win import write_to_window

# Inside a curses application
write_to_window(stdscr, ascii_art.frame("Status: OK"), y=2, x=5)

CLI

# Text banners
ascii-art text "Hello World" --font slant --width 100 --align center

# Image conversion
ascii-art image photo.png --width 80 --invert
ascii-art image diagram.png --edges

# Shape drawing
ascii-art shape circle --width 40 --height 20 --char "o"
ascii-art shape rectangle --width 30 --height 15
ascii-art shape diamond --char "+"

# Border framing (text argument or stdin)
ascii-art border "important text" --style rounded --title "Notice"
echo "piped text" | ascii-art border --style double

# Table from CSV (argument or stdin)
ascii-art table "Name,Score\nAlice,92\nBob,87" --headers --style bold
cat data.csv | ascii-art table --headers

# Charts
ascii-art chart "1,4,2,8,5,7" --type bar --width 30
ascii-art chart "1,4,2,8,5,7" --type sparkline

Development

# Create virtual environment and install dev dependencies
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Run tests
pytest

# Run a single test
pytest tests/test_shapes.py::test_rectangle -v

# Performance benchmarks
pytest -m perf

# Type checking (strict mode)
mypy src/

# Lint
ruff check src/ tests/

# Build distribution
python -m build

Project Structure

src/ascii_art/
├── __init__.py          # Public API re-exports
├── __main__.py          # CLI entry point
├── _types.py            # Enums, type aliases, character ramps
├── _builder.py          # BaseBuilder ABC (fluent API pattern)
├── _cache.py            # @cached decorator
├── text.py              # Figlet text rendering
├── image.py             # Image-to-ASCII conversion
├── shapes.py            # Canvas + drawing primitives
├── borders.py           # Frame/divider rendering
├── tables.py            # ASCII table rendering
├── charts.py            # Sparkline, bar chart, scatter plot
├── sprites.py           # Sprite transforms & animation
└── integrations/        # Rich, Textual, curses adapters

Requirements

  • Python 3.10+
  • pyfiglet — text rendering
  • Pillow — image conversion

Metadata

Release files for tui-ascii-art 0.1.1

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

Source distribution (sdist)

Source distribution for tui-ascii-art 0.1.1
File Size Uploaded Provenance Actions
tui_ascii_art-0.1.1.tar.gz 30.9 kB With provenance Details for tui_ascii_art-0.1.1.tar.gz

Release files / tui_ascii_art-0.1.1.tar.gz

Download URL tui_ascii_art-0.1.1.tar.gz
Size 30.9 kB
Tags Source
SHA-256 checksum
How to use checksums
4379c57cf1e2bf7c88d8b1097535311b47ce187ed68788adab5c29252cedf748
BLAKE2b-256 checksum
How to use checksums
f2a8d23fe110e9b4e3fb1f1e756791d6790e06aa6b0e24a539ace11a701abebc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 4, 2026.

Transparency log

Security for tui-ascii-art 0.1.1

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.

Full provenance

All 1 file in this release has been uploaded with provenance metadata.

Attestation for tui_ascii_art-0.1.1.tar.gz

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 Mar 4, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

1 release file Full provenance

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