Modern Python library for building beautiful terminal applications.
Project description
EightBits Terminal by 8 Bits
Biblioteca moderna para crear aplicaciones de terminal elegantes en Python, con entrada de datos validada, salida con colores y alineación, tablas formateadas y formateo de números/fechas según el locale.
📦 Instalación
pip install eightbits-terminal
Requisitos: Python 3.9 o superior.
🧩 Módulos
La librería está organizada en seis clases de utilidad estática (ninguna se
instancia; todos sus métodos son @staticmethod), cada una con una única
responsabilidad:
| Clase | Responsabilidad |
|---|---|
Input |
Leer y validar datos ingresados por el usuario |
Output |
Escribir en la consola (imprimir, limpiar, colorear, alinear) |
Format |
Transformar números y fechas en texto formateado, sin imprimir nada |
Colors |
Códigos ANSI de color y utilidades para aplicarlos a un texto |
Alignment |
Constantes y validación de alineación de texto |
Tabular |
Renderizar listas de diccionarios como tabla en consola |
Nota sobre
FormatvsOutput: si vienen de una versión anterior de esta librería,Outputsolía incluirformat_int(),format_currency(),set_locale(), etc. Esos métodos se movieron a la claseFormat, porque son funciones puras de transformación de datos (no hacen I/O de consola) y merecían vivir separadas deOutput. Ver Migrando desde v1.x.
Input
Entrada de datos por consola, con validación integrada y reintento automático ante datos inválidos.
Input.text(prompt, color_prompt=Colors.DEFAULT, color_input=Colors.DEFAULT) -> str
Input.integer(prompt, color_prompt, color_input, min_value=None, max_value=None) -> int
Input.float(prompt, color_prompt, color_input, min_value=None, max_value=None) -> float
Input.confirm(prompt, color_prompt, color_input) -> bool
Input.date(prompt, color_prompt, color_input) -> str
Input.email(prompt, color_prompt, color_input) -> str
Input.password(prompt, color_prompt, color_input) -> str
Input.choice(title, options, color_prompt, color_input) -> int
password()usagetpassinternamente, así que la contraseña no se muestra en pantalla mientras se escribe (esto significa que no funciona si se simula la entrada coninput()mockeado en tests; hay que mockeargetpass.getpassen su lugar, o alimentarstdindirectamente).choice()valida que la opción elegida sea un número dentro del rango de opciones ofrecidas, y vuelve a preguntar si no lo es.
Output
Todo lo que efectivamente escribe algo en la consola.
Output.print(*objects, sep=' ', end='\n', color=Colors.DEFAULT,
alignment=Alignment.LEFT, width=0, fill=True,
file=None, flush=False) -> None
Output.clear() -> None
Output.console_size() -> tuple[int, int]
Output.press_enter_to_continue() -> None
Output.error(message: str) -> None
Output.warning(message: str) -> None
Output.confirm(message: str) -> bool
Output.typewriter(text: str) -> None
Output.print_title(title, color, underline="*", alignment=Alignment.CENTER) -> None
Output.show_progress_bar(iteration: int, total: int, length: int = 50) -> None
Detalles a tener en cuenta:
colorva siempre como argumento nombrado, nunca posicional:Output.print("hola", color=Colors.GREEN), noOutput.print("hola", Colors.GREEN). Comoprint()recibe*objectsprimero, pasar el color sincolor=hace que se trate como un objeto más a imprimir, en vez de aplicarse como color.fillcontrola si el texto se rellena hasta el ancho de la consola (True, por defecto, pensado para líneas completas) o se imprime tal cual (False, pensado para fragmentos de una misma línea, como celdas de una tabla que se arman con varias llamadas seguidas).filepermite redirigir la salida (por ejemplo asys.stderr, o a unio.StringIO()en un test) sin tocar la consola real.error()escribe ensys.stderr; el resto de los métodos (incluidowarning()) escriben ensys.stdout. En una terminal normal esto no se nota (ambos streams se ven mezclados en pantalla); la diferencia importa si alguien redirige la salida estándar a un archivo.show_progress_bar()lanzaValueErrorsitotal <= 0o siiterationestá fuera de[0, total], en vez de fallar silenciosamente o dividir por cero.
Format
Funciones puras: reciben un dato, devuelven un str ya formateado. No
imprimen nada ni dependen de Colors/Alignment.
Format.set_locale(region: str) -> None
Format.integer_number(value: int) -> str
Format.float_number(value: float) -> str
Format.currency_number(value: float) -> str
Format.percentage_number(value: float) -> str
Format.date(date, custom_locale="", short_format=True) -> str
- Todas (salvo
date()conshort_format=False, que usa%Bdel locale activo) dependen del locale configurado conset_locale(). Si no se llamó aset_locale(), se usa el locale por defecto del sistema. set_locale()modifica el locale de todo el proceso (usa el módulolocalede Python, que es estado global, no por hilo). Si tu aplicación usa threads o async, tenelo en cuenta: cambiar el locale desde un hilo afecta a los demás.date()restaura el locale original al terminar si se le pasócustom_locale, incluso si ese locale no existe en el sistema (en ese caso, sigue con el locale que ya estaba activo, sin lanzar excepción).
Colors
Constantes de color ANSI y utilidades para aplicarlas a un texto sin pasar
por Output (por ejemplo, para componer un string coloreado antes de
imprimirlo con otra herramienta).
Colors.RED, Colors.GREEN, Colors.YELLOW, Colors.BLUE,
Colors.MAGENTA, Colors.CYAN, Colors.WHITE, Colors.DEFAULT,
Colors.BOLD, Colors.UNDERLINE
Colors.validate_color(color: str) -> str # color si es válido, si no Colors.DEFAULT
Colors.colorize(text: str, color: str) -> str
Colors.bold(text: str) -> str
Colors.underline(text: str) -> str
Alignment
Constantes de alineación, usadas por Output.print(), Output.print_title()
y Tabular.
Alignment.LEFT # 'left'
Alignment.CENTER # 'center'
Alignment.RIGHT # 'right'
Alignment.validate_alignment(alignment: str) -> str # alignment si es válido, si no Alignment.LEFT
Tabular
Renderiza una lista de diccionarios como tabla, ajustando el ancho de las columnas al espacio disponible (dividiendo el contenido en varias líneas si hace falta).
Tabular.print(data: list[dict], title: str = "", max_width: int = 0) -> None
- Todas las filas de
datadeben tener las mismas claves; las claves del primer diccionario se usan como encabezado de columna. - Si
max_widthes 0 (por defecto), usa el ancho actual de la terminal. - Si
dataestá vacío, imprime"No hay datos para mostrar."en vez de una tabla vacía.
🎮 Ejemplo de uso
import time
from datetime import datetime
from eightbits import Input, Output, Colors, Alignment, Tabular, Format
# --- Entrada de datos ---
nombre = Input.text("Ingrese su nombre: ", Colors.GREEN, Colors.BLUE)
edad = Input.integer("Ingrese su edad: ", Colors.GREEN, Colors.BLUE, 0, 120)
peso = Input.float("Ingrese su peso: ", Colors.GREEN, Colors.BLUE, 50, 150)
continuar = Input.confirm("¿Deseas continuar? (si/no): ", Colors.GREEN, Colors.BLUE)
# --- Salida formateada (color siempre como argumento nombrado) ---
Output.print(nombre, color=Colors.WHITE)
Output.print(edad, color=Colors.WHITE)
Output.print(peso, color=Colors.WHITE)
Output.print(continuar, color=Colors.WHITE)
Output.warning("Esto es un mensaje de advertencia.")
Output.error("Esto es un mensaje de error.") # va a sys.stderr
Output.confirm("Esto es un mensaje de confirmación.")
Output.clear()
# --- Formateo de datos (clase Format, separada de Output) ---
Format.set_locale("es_AR.UTF-8")
Output.print(f"Mi sueldo es de {Format.currency_number(367000)}", color=Colors.GREEN)
Output.print(f"Número formateado: {Format.integer_number(1000)}")
Output.print(f"Porcentaje: {Format.percentage_number(99.99)}")
Output.print(f"Fecha: {Format.date(datetime.now())}")
# --- Alineación de texto ---
Output.print("Texto alineado a la izquierda")
Output.print("Texto centrado", color=Colors.BLUE, alignment=Alignment.CENTER)
Output.print("Texto alineado a la derecha", alignment=Alignment.RIGHT)
# --- Tabla ---
data = [
{"nombre": "Juan Carlos González", "ciudad": "Madrid"},
{"nombre": "María", "ciudad": "Barcelona"},
]
Tabular.print(data, title="Lista de Usuarios")
Tabular.print(data, title="Lista de Usuarios", max_width=80) # ancho fijo
# --- Barra de progreso ---
total = 100
for i in range(total + 1):
Output.show_progress_bar(i, total)
time.sleep(0.02)
# --- Título con subrayado ---
Output.print_title("Esto es un título", Colors.GREEN, "=", Alignment.CENTER)
Un ejemplo más completo, que recorre todos los métodos de la librería, está
en examples/demo.py. Para ejecutarlo:
python -m examples.demo
🔄 Migrando desde v1.x
Si tu código llama a estos métodos de Output, reemplazalos por sus
equivalentes en Format:
Antes (Output) |
Ahora (Format) |
|---|---|
Output.set_locale(...) |
Format.set_locale(...) |
Output.format_int(...) |
Format.integer_number(...) |
Output.format_float(...) |
Format.float_number(...) |
Output.format_currency(...) |
Format.currency_number(...) |
Output.format_percentage(...) |
Format.percentage_number(...) |
Output.format_date(...) |
Format.date(...) |
Además, si llamabas a Output.print(texto, Colors.ALGO) pasando el color
como segundo argumento posicional, cambialo a
Output.print(texto, color=Colors.ALGO): la firma actual recibe *objects
primero, así que un color sin color= se trataba (incorrectamente) como
otro texto más a imprimir, y nunca se aplicaba.
🧪 Tests
pip install pytest
pytest
🛠️ Requisitos
- Python 3.9 o superior
📜 Licencia
Este proyecto está bajo la Licencia MIT. Ver el archivo LICENSE para más detalles.
🎥 Video de presentación
🤝 Contribuir
Las contribuciones son bienvenidas. Por favor, siéntete libre de:
- Reportar bugs
- Sugerir nuevas funcionalidades
- Enviar pull requests
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eightbits_terminal-2.0.1.tar.gz.
File metadata
- Download URL: eightbits_terminal-2.0.1.tar.gz
- Upload date:
- Size: 24.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c12b750402447c19e1c17701e529b0ba1316db074952d6f73dd690d88836edf
|
|
| MD5 |
5ae928b0f1103805137cc30e9c13815c
|
|
| BLAKE2b-256 |
2d452ec1602dadc9fe5183b212b73b69057dfadb2609959b4c1afc2fd91349a5
|
Provenance
The following attestation bundles were made for eightbits_terminal-2.0.1.tar.gz:
Publisher:
python-publish.yml on agustincomolli/eightbits-terminal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
eightbits_terminal-2.0.1.tar.gz -
Subject digest:
8c12b750402447c19e1c17701e529b0ba1316db074952d6f73dd690d88836edf - Sigstore transparency entry: 2187658787
- Sigstore integration time:
-
Permalink:
agustincomolli/eightbits-terminal@5821a19798f4804a8b18ca641d084db69ebdd946 -
Branch / Tag:
refs/tags/v2.0.1 - Owner: https://github.com/agustincomolli
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@5821a19798f4804a8b18ca641d084db69ebdd946 -
Trigger Event:
release
-
Statement type:
File details
Details for the file eightbits_terminal-2.0.1-py3-none-any.whl.
File metadata
- Download URL: eightbits_terminal-2.0.1-py3-none-any.whl
- Upload date:
- Size: 17.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c39a7cdea48d8540ad7a6e890adb258fd2620b8fac996b911acf082b863aeed
|
|
| MD5 |
72b802384782e371b10cac1989222cbe
|
|
| BLAKE2b-256 |
b0f0babf5562da9ab6738209b74fd9b3659735c14b7fd640f7b7d7a289b74856
|
Provenance
The following attestation bundles were made for eightbits_terminal-2.0.1-py3-none-any.whl:
Publisher:
python-publish.yml on agustincomolli/eightbits-terminal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
eightbits_terminal-2.0.1-py3-none-any.whl -
Subject digest:
7c39a7cdea48d8540ad7a6e890adb258fd2620b8fac996b911acf082b863aeed - Sigstore transparency entry: 2187658818
- Sigstore integration time:
-
Permalink:
agustincomolli/eightbits-terminal@5821a19798f4804a8b18ca641d084db69ebdd946 -
Branch / Tag:
refs/tags/v2.0.1 - Owner: https://github.com/agustincomolli
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@5821a19798f4804a8b18ca641d084db69ebdd946 -
Trigger Event:
release
-
Statement type: