quickqr-cli: QR codes desde la terminal, sin pagar suscripciones ni dejar tu data

Generá QR codes desde la terminal con Python. Detecta teléfonos, soporta MECARD y colores personalizados.

Share
quickqr-cli: QR codes desde la terminal, sin pagar suscripciones ni dejar tu data
Photo by Brett Jordan / Unsplash

Desde hace tiempo quería una forma de generar QR codes directamente desde la terminal, algo que no me obligara a abrir el navegador, entrar a una página llena de publicidad, aceptar cookies, y luego descargar la imagen. La mayoría de generadores online que encuentras son SaaS disfrazados: te dejan hacer dos o tres y después te piden una suscripción. Como canta El Cuarteto de Nos: «Sea con dinero o no, siempre se paga un favor».

"Nada es gratis en la vida" — El Cuarteto de Nos

Así que hice lo que cualquier desarrollador haría: escribí mi propio generador en Python. Un solo archivo, cero dependencias pesadas, y que funcione en cualquier equipo donde tenga Python y uv. El resultado es quickqr-cli.

¿Qué hace y cómo funciona?

qrgen.py es un único archivo que recibe una URL o un número de teléfono y genera un PNG listo para usar. El shebang #!/usr/bin/env -S uv run lo hace directamente ejecutable sin instalación previa:

./qrgen.py https://audeldiaz.work

Eso es todo. Sales con un audeldiaz.work.png listo para compartir.

Las dependencias son mínimas: typer para el CLI y qrcode[pil] para la generación de imágenes. Todo se gestiona con uv sync y tienes el entorno listo en segundos.

Typer y FastAPI: proyectos colombianos con impacto global

Para el CLI usé Typer, creado por Sebastián Ramírez (tiangolo), el mismo detrás de FastAPI, uno de mis frameworks favoritos para construir APIs. Ya había hablado de FastAPI en mi post sobre Dev Containers y tengo el repo AudelDiaz/fastapi-devcontainers. Me encanta que sean proyectos liderados por un colombiano y que tengan impacto global.

Con Typer escribí el CLI completo sin enredarme en cómo capturar ni validar los argumentos. El sistema de tipos de Python define automáticamente los argumentos, el --help se genera solo, y la validación viene incluida.

Detección inteligente de teléfonos

Una de las cosas que más me molestaba de otros generadores es que trataban todo como texto plano. Si querías generar un QR para un número de teléfono, tenías que acordarte de anteponer tel: manualmente.

En quickqr-cli, si el input empieza con + o contiene solo dígitos, espacios, guiones y paréntesis, automáticamente se trata como un número de teléfono:

./qrgen.py +15551234567

Esto genera un QR con el formato tel:+15551234567 que al escanearlo abre el marcador del teléfono directamente.

La lógica es bastante simple:

def _is_phone(text: str) -> bool:
    stripped = text.strip()
    if stripped.startswith("+"):
        return True
    allowed = stripped.replace(" ", "").replace("-", "").replace("(", "").replace(")", "")
    return allowed.isdigit()

MECARD para contactos

Si además del teléfono tienes un nombre, el flag --name genera un QR en formato MECARD, el estándar que iOS y Android entienden nativamente:

./qrgen.py +15551234567 -n "Audel Diaz"

Al escanear el QR con la cámara del celular, te aparece la opción de guardar el contacto al instante. Sin apps intermedias, sin servicios de terceros.

Personalización

El QR que acompaña este post es https://audeldiaz.work con colores personalizados:

./qrgen.py https://audeldiaz.work --fill-color "#1a1a2e" --back-color "#eaeaea"
https://audeldiaz.work

Puedes ajustar el tamaño de cada módulo con --box-size, el borde con --border, y el nivel de corrección de errores con --ec (L, M, Q, H). Para un QR que va en una etiqueta pequeña, uso --box-size 6 --border 2 --ec H.

Pruebas

El repo incluye 25 tests con pytest que cubren desde la detección de teléfonos hasta la generación real de PNG. No hay nada más satisfactorio que hacer un cambio y saber que todo sigue funcionando con uv run pytest -v.

Si quieres probarlo, el repo es público: github.com/AudelDiaz/quickqr-cli.

Gracias por llegar hasta este punto. Nos vemos en el próximo post.