Blessed

A Python terminal handling library. Works as a thin wrapper around curses, providing cross-platform support and a simple API.

TUITerminalCursesCross-platformSimple

GitHub Overview

jquast/blessed

Blessed is an easy, practical library for making python terminal apps

Stars1,295
Watchers25
Forks76
Created:March 1, 2014
Language:Python
License:MIT License

Topics

clicursesterminal

Star History

jquast/blessed Star History
Data as of: 7/25/2025, 06:23 AM

Blessed

Blessed is a library that simplifies Python terminal handling. It works as a thin wrapper around the curses library, providing cross-platform support and a simple API. It hides the complexity of curses and enables more intuitive terminal application development.

Key Features

Simple API

  • Intuitive Interface: Hides the complexity of curses
  • Method Chaining: Concise notation with method chaining
  • Context Managers: Automated resource management

Cross-Platform

  • Windows Support: Utilizes Windows Console API
  • Unix Support: Uses ncurses/curses libraries
  • Consistent API: Abstracts platform differences

Rich Functionality

  • Colors and Styles: 256-color and RGB color support
  • Position Control: Precise cursor position control
  • Key Input: Special key detection and handling

Installation

pip install blessed

Basic Usage

Terminal Initialization

from blessed import Terminal

term = Terminal()

print(term.home + term.clear)  # Clear screen
print(term.move_y(10) + "Hello, World!")  # Move to line 10 and output

Colors and Styles

from blessed import Terminal

term = Terminal()

# Basic colors
print(term.red("Red text"))
print(term.green("Green text"))
print(term.blue("Blue text"))

# Background colors
print(term.on_yellow("Text on yellow background"))

# Styles
print(term.bold("Bold text"))
print(term.italic("Italic text"))
print(term.underline("Underlined text"))

# Combinations
print(term.bold_red_on_yellow("Bold red text on yellow background"))

Key Input Handling

from blessed import Terminal

term = Terminal()

print("Press any key (ESC to quit):")

with term.cbreak(), term.hidden_cursor():
    while True:
        key = term.inkey()
        
        if key.is_sequence:
            print(f"Special key: {key.name}")
        else:
            print(f"Character: {key}")
        
        if key.name == 'KEY_ESCAPE':
            break

Screen Control

from blessed import Terminal

term = Terminal()

with term.fullscreen(), term.cbreak():
    # Fullscreen mode
    print(term.move(5, 10) + "Positioned text")
    print(term.move(10, 20) + term.red("Red text at specific position"))
    
    # Draw border
    for x in range(term.width):
        print(term.move(0, x) + "*", end="")
        print(term.move(term.height - 1, x) + "*", end="")
    
    for y in range(term.height):
        print(term.move(y, 0) + "*", end="")
        print(term.move(y, term.width - 1) + "*", end="")
    
    term.inkey()  # Wait for key input

Practical Examples

Menu System

from blessed import Terminal

def show_menu(term, options, selected=0):
    term.clear()
    print(term.move(2, 5) + term.bold("Select an option:"))
    
    for i, option in enumerate(options):
        y = 4 + i
        if i == selected:
            print(term.move(y, 5) + term.reverse(f"> {option}"))
        else:
            print(term.move(y, 5) + f"  {option}")

def main():
    term = Terminal()
    options = ["Option 1", "Option 2", "Option 3", "Exit"]
    selected = 0
    
    with term.fullscreen(), term.cbreak():
        while True:
            show_menu(term, options, selected)
            
            key = term.inkey()
            
            if key.name == 'KEY_UP' and selected > 0:
                selected -= 1
            elif key.name == 'KEY_DOWN' and selected < len(options) - 1:
                selected += 1
            elif key.name == 'KEY_ENTER':
                if selected == len(options) - 1:  # Exit
                    break
                else:
                    print(term.move(10, 5) + f"You selected: {options[selected]}")
                    term.inkey()
            elif key.name == 'KEY_ESCAPE':
                break

if __name__ == "__main__":
    main()

Progress Bar

from blessed import Terminal
import time

def show_progress(term, progress, total):
    width = 50
    filled = int(width * progress / total)
    bar = "=" * filled + "-" * (width - filled)
    percentage = int(100 * progress / total)
    
    print(term.move(10, 10) + f"Progress: [{bar}] {percentage}%")

def main():
    term = Terminal()
    
    with term.fullscreen():
        print(term.move(8, 10) + term.bold("Processing..."))
        
        for i in range(101):
            show_progress(term, i, 100)
            time.sleep(0.1)
        
        print(term.move(12, 10) + term.green("Complete!"))
        term.inkey()

if __name__ == "__main__":
    main()

Basic Text Editor Features

from blessed import Terminal

class SimpleEditor:
    def __init__(self):
        self.term = Terminal()
        self.lines = [""]
        self.cursor_x = 0
        self.cursor_y = 0
    
    def draw(self):
        print(self.term.home + self.term.clear)
        
        # Status line
        status = f"Line: {self.cursor_y + 1}, Col: {self.cursor_x + 1}"
        print(self.term.move(0, 0) + self.term.reverse(status.ljust(self.term.width)))
        
        # Text display
        for i, line in enumerate(self.lines):
            print(self.term.move(i + 2, 0) + line)
        
        # Cursor position
        print(self.term.move(self.cursor_y + 2, self.cursor_x), end="")
    
    def run(self):
        with self.term.fullscreen(), self.term.cbreak():
            while True:
                self.draw()
                key = self.term.inkey()
                
                if key == chr(27):  # ESC
                    break
                elif key.name == 'KEY_UP' and self.cursor_y > 0:
                    self.cursor_y -= 1
                    self.cursor_x = min(self.cursor_x, len(self.lines[self.cursor_y]))
                elif key.name == 'KEY_DOWN' and self.cursor_y < len(self.lines) - 1:
                    self.cursor_y += 1
                    self.cursor_x = min(self.cursor_x, len(self.lines[self.cursor_y]))
                elif key.name == 'KEY_LEFT' and self.cursor_x > 0:
                    self.cursor_x -= 1
                elif key.name == 'KEY_RIGHT' and self.cursor_x < len(self.lines[self.cursor_y]):
                    self.cursor_x += 1
                elif key and not key.is_sequence:
                    # Character input
                    line = self.lines[self.cursor_y]
                    self.lines[self.cursor_y] = line[:self.cursor_x] + key + line[self.cursor_x:]
                    self.cursor_x += 1

if __name__ == "__main__":
    editor = SimpleEditor()
    editor.run()

Comparison with Other Libraries

FeatureBlessedcursesRichUrwid
Cross-platform×
SimplicityHighLowMediumLow
Learning CurveLowHighMediumHigh
Feature RichnessMediumHighHighHigh
PerformanceHighHighMediumMedium

Use Cases

  • Command Line Tools: Interactive CLI applications
  • System Monitoring: Real-time status displays
  • Games: Simple terminal games
  • Educational Tools: Programming learning support tools

Community and Support

  • GitHub: Active maintenance
  • Documentation: Detailed API reference
  • Compatibility: Python 2.7-3.11 support
  • Stability: Long-term proven track record

Blessed is a practical and reliable library that provides powerful terminal control features while hiding the complexity of curses.