¿Qué es TOML?
TOML — Tom's Obvious Minimal Language — es un formato de archivo de configuración creado por Tom Preston-Werner (co-fundador de GitHub) en 2013. Está diseñado para ser inequívoco, fácil de leer y escribir por humanos, y fácil de mapear directamente a una tabla hash en cualquier lenguaje de programación.
TOML se ha convertido en el formato de configuración estándar para:
- Rust —
Cargo.toml(manifiestos de paquetes y configuración de workspace) - Python —
pyproject.toml(configuración del sistema de construcción PEP 518/517) - Hugo — configuración del generador de sitios estáticos (
hugo.toml)
Sintaxis TOML
Pares Clave/Valor Básicos
# Esto es un comentario
nombre = "Mi Aplicación"
version = "1.2.0"
depurar = false
max_conexiones = 100
pi = 3.14159
Tipos de Cadenas
# Cadenas básicas — escapes con barra invertida
saludo = "¡Hola, Mundo!\nNueva línea."
ruta = "C:\\Users\\alicia\\Documentos"
# Cadenas literales (comillas simples) — sin procesamiento de escapes
regex = '\d+\.\d+'
ruta_windows = 'C:\Users\alicia\Documentos'
# Cadena multilínea básica (triple comillas dobles)
descripcion = """
Esto es una cadena
multilínea en TOML.
"""
# Cadena multilínea literal (triple comillas simples)
regex_crudo = '''
\d{4}-\d{2}-\d{2}
'''
Números y Booleanos
puerto = 8080
negativo = -42
hex = 0xDEADBEEF
numero_grande = 1_000_000
pi = 3.14159
activado = true
detallado = false
Tipos de Fecha y Hora (Únicos en TOML)
TOML tiene soporte de primera clase para fechas y horas:
creado_en = 2024-04-15T14:30:00Z
actualizado_en = 2024-04-15T16:45:00+02:00
cumpleanos = 1990-06-20
alarma = 07:30:00
Arrays
frutas = ["manzana", "plátano", "cereza"]
puertos = [8080, 8443, 9000]
ips_permitidas = [
"192.168.1.1",
"10.0.0.1",
"172.16.0.0",
]
Tablas (Diccionarios)
[servidor]
host = "localhost"
puerto = 5432
[servidor.opciones]
tiempo_espera = 30
reintento = true
[base_de_datos]
url = "postgresql://localhost/mibbd"
tamanio_pool = 10
punto = {x = 10, y = 20}
Arrays de Tablas
[[productos]]
nombre = "Widget A"
precio = 9.99
sku = "WA-001"
[[productos]]
nombre = "Widget B"
precio = 24.99
sku = "WB-002"
Ejemplos Reales de TOML
Python pyproject.toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "mi-paquete"
version = "1.0.0"
description = "Un paquete Python útil"
readme = "README.md"
requires-python = ">=3.10"
authors = [
{name = "Alicia García", email = "alicia@ejemplo.com"},
]
dependencies = [
"requests>=2.28",
"pydantic>=2.0",
]
[project.optional-dependencies]
dev = ["pytest", "black", "ruff", "mypy"]
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--cov=src"
[tool.black]
line-length = 88
Trabajar con TOML en Python
Python 3.11+: tomllib integrado
import tomllib
# Leer un archivo TOML
with open('pyproject.toml', 'rb') as f:
config = tomllib.load(f)
print(config['project']['name'])
print(config['project']['version'])
tomli: Retrocompatibilidad para Python 3.10 e Inferiores
pip install tomli
try:
import tomllib # Python 3.11+
except ImportError:
import tomli as tomllib # Python 3.10-
with open('config.toml', 'rb') as f:
config = tomllib.load(f)
tomli-w: Escribir TOML
pip install tomli-w
import tomli_w
config = {
'nombre': 'Mi App',
'version': '1.0.0',
'servidor': {'host': 'localhost', 'puerto': 8080},
'caracteristicas': ['auth', 'cache', 'logging'],
'depurar': False,
}
with open('config.toml', 'wb') as f:
tomli_w.dump(config, f)
cadena_toml = tomli_w.dumps(config)
print(cadena_toml)
Convertir Entre TOML, JSON y YAML
try:
import tomllib
except ImportError:
import tomli as tomllib
import json, yaml, tomli_w
def toml_a_json(ruta_toml: str, ruta_json: str) -> None:
with open(ruta_toml, 'rb') as f:
datos = tomllib.load(f)
with open(ruta_json, 'w', encoding='utf-8') as f:
json.dump(datos, f, indent=2, default=str)
def toml_a_yaml(ruta_toml: str, ruta_yaml: str) -> None:
with open(ruta_toml, 'rb') as f:
datos = tomllib.load(f)
with open(ruta_yaml, 'w', encoding='utf-8') as f:
yaml.dump(datos, f, default_flow_style=False, allow_unicode=True)
def json_a_toml(ruta_json: str, ruta_toml: str) -> None:
with open(ruta_json, 'r', encoding='utf-8') as f:
datos = json.load(f)
with open(ruta_toml, 'wb') as f:
tomli_w.dump(datos, f)
toml_a_json('pyproject.toml', 'pyproject.json')
TOML vs JSON vs YAML: Comparativa
| Característica | TOML | JSON | YAML |
|---|---|---|---|
| Legibilidad humana | Excelente | Buena | Buena |
| Comentarios | Sí (#) |
No | Sí (#) |
| Cadenas multilínea | Sí (triple comillas) | No | Sí (escalares de bloque) |
| Tipos fecha/hora | Sí (nativo) | No | Parcial |
| Tipado estricto | Muy estricto | Moderado | Laxo |
| Anchors/aliases | No | No | Sí |
| Sensible a espacios | No | No | Sí (indentación) |
| Caso de uso | Archivos de config | APIs, serialización | Config, DevOps |
Elige TOML cuando: Escribas un archivo de configuración que los humanos editarán a mano; necesites valores de fecha/hora sin comillas; el ecosistema lo espere (proyectos Rust, empaquetado Python).
Conversiones relacionadas
Conversiones frecuentes del catálogo: