Skip to content

jparradog/suvalor

suvalor

Cliente no oficial y de linea de comandos para descargar, de forma incremental y reproducible, documentacion contable propia desde el portal Suvalor / Cibest Capital (Valores Bancolombia) en suvalor.com.

CI License: Apache 2.0 Python: 3.10+ Disclaimer

⚠️ LEA DISCLAIMER.md ANTES DE USAR ESTE CLIENTE. Esto es software no oficial. No estoy afiliado a Bancolombia, Valores Bancolombia, Cibest Capital ni Suvalor. Usar este cliente puede violar los terminos del portal y derivar en sancion sobre la cuenta del usuario. Se usa bajo riesgo y responsabilidad propios.


Que hace

Automatiza la descarga de:

  • Documentos contables (RC, NC, CE por default; FB/PB opt-in) por rangos de fecha, con inventario incremental: solo descarga lo que falta.
  • Extractos consolidados mensuales (PDF) — los ultimos 12 meses disponibles.
  • Snapshot del portafolio consolidado (XLS).
  • Movimientos de Tesoreria (PDF/XLS) dentro de sync por default, con comando opt-in para rangos explicitos.

Todo en una sola sesion de Playwright + un solo login manual cuando se usa sync.

Que NO hace

  • No automatiza el login. El portal usa un teclado virtual que cambia de posicion + reCAPTCHA. El cliente abre el navegador y cede el control al usuario; el usuario autentica manualmente y el cliente toma el control despues.
  • No evade reCAPTCHA, OTP ni 2FA.
  • No envia ni almacena credenciales. Las cookies viven en el perfil persistente de Chrome local (_chrome_profile/), nunca abandonan el equipo del usuario.

Por que existe

Porque sacar 80+ documentos contables a mano tipeando rangos de 89 dias en un formulario ASP.NET es tortura. Si el portal ofreciera una API, esto no seria necesario.


Requisitos

  • Python ≥ 3.10
  • uv (recomendado) o pip.
  • Google Chrome instalado en el sistema. El cliente usa Chrome real (no Chromium) porque reCAPTCHA bloquea Chromium controlado.

Para instalar uv:

# Windows
winget install --id=astral-sh.uv -e

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

Instalacion

git clone https://github.com/jparradog/suvalor.git
cd suvalor
uv sync
uv run playwright install

Migracion desde 0.2.x

Si se venia usando una version anterior con layout _script/suvalor/ dentro de la carpeta de datos, ver CHANGELOG.md para la guia paso a paso de migracion.

Configuracion: SUVALOR_HOME

suvalor necesita un directorio de datos donde escribir:

  • Inventarios JSON (_state/)
  • Perfil persistente de Chrome (_chrome_profile/)
  • Carpetas de salida (2024/, 2025/, Extractos/, Cartera/, ...)
  • Logs (_state/run.log)

Por seguridad, este directorio debe ser distinto del repositorio del codigo.

Hay dos formas de indicarlo:

Opcion A: variable de entorno (recomendado)

# Linux / macOS
export SUVALOR_HOME=~/Documents/suvalor-data
mkdir -p "$SUVALOR_HOME"

# Windows PowerShell
$env:SUVALOR_HOME = "$HOME\Documents\suvalor-data"
mkdir $env:SUVALOR_HOME

# Windows CMD
set SUVALOR_HOME=%USERPROFILE%\Documents\suvalor-data
mkdir %SUVALOR_HOME%

Opcion B: cwd al invocar

Si SUVALOR_HOME no esta definida, el cliente usa el directorio activo desde el que se invoca el comando:

cd ~/Documents/suvalor-data
uv run --directory /path/to/suvalor-repo suvalor sync

⚠️ No se debe apuntar SUVALOR_HOME al repositorio del codigo. El .gitignore protege contra accidentes, pero la mejor proteccion es la separacion fisica.


Uso

Todos los ejemplos asumen que SUVALOR_HOME apunta a la carpeta de datos.

Sincronizar todo (default)

uv run suvalor              # equivalente a `uv run suvalor sync`
uv run suvalor sync

sync ejecuta docs + extractos + cartera + tesoreria en una sola sesion con un solo login manual. Imprime una tabla rich con el resumen al final.

Si una etapa falla (sesion expirada, error de red), las demas siguen y el resumen lo refleja. Exit code 0 si todo OK, 3 si hubo errores parciales.

Flags utiles:

uv run suvalor sync --no-docs              # saltar documentos
uv run suvalor sync --no-extractos         # saltar extractos
uv run suvalor sync --no-cartera           # saltar snapshot de cartera
uv run suvalor sync --no-tesoreria         # saltar movimientos de Tesoreria
uv run suvalor sync --types RC,NC          # filtrar tipos de docs
uv run suvalor sync --backfill             # docs: historico desde 2024-01-01

Smoke test (recomendado primero)

uv run suvalor descargar --smoke-test --types RC --max-docs 3

Ultimos 30 dias, solo Recibos de Caja, max 3 docs.

Solo documentos (incremental)

uv run suvalor descargar

Consulta desde retro_days antes de la ultima corrida hasta hoy. Salta documentos que ya estan en el inventario. Por default usa solo RC, NC, CE. FB y PB son opt-in con --types; CC queda como tipo legacy local para leer inventarios/estado historico, pero ya no se consulta en el selector actual del portal.

Backfill historico

uv run suvalor descargar --backfill

Consulta todo desde 2024-01-01.

Rango personalizado

uv run suvalor descargar --from 2025-06-01 --to 2025-09-30

Tipos de documento

Codigo Tipo Notas
RC Recibos de Caja Default
NC Notas Contables Default
CE Comprobantes de Egreso Default
FB Facturas de Bolsa Opt-in (--types FB); no default
PB Papeletas de Bolsa Opt-in (--types PB); no default
CC Certificados de Custodia Legacy local; no disponible para consultas nuevas

El selector actual del portal expone CE, FB, NC, PB y RC. Si un config.toml antiguo o un --types explicito incluye CC, el comando falla antes de abrir el navegador y pide usar tipos actuales. En recuperar-fallidos, las filas legacy CC se reportan como saltadas; si no queda ningun tipo actual para reintentar, no se abre Chrome ni se pide login.

Otros subcomandos

Comando Que hace
suvalor sync (default) Ejecuta docs + extractos + cartera + tesoreria.
suvalor extractos Sincroniza extractos consolidados (PDF).
suvalor cartera Snapshot del portafolio actual (XLS).
suvalor tesoreria Descarga opt-in/debug de movimientos de Tesoreria por rango explicito.
suvalor fondos Prepara movimientos de Fondos en modo fail-closed; no automatiza pagina aun.
suvalor inventario Resumen del inventario actual.
suvalor reset Borra _state/inventario.json y _state/ultima_corrida.json.
suvalor recuperar-fallidos Reintenta cada fallo en _Fallidos/fallos.tsv.
suvalor config show Muestra la configuracion efectiva.
suvalor config init Crea _state/config.toml con un template editable.
suvalor timings Muestra los percentiles aprendidos por operacion.

Tesoreria en sync y comando opt-in

suvalor sync incluye movimientos de Tesoreria por defecto. Para apagar esa etapa en una corrida use --no-tesoreria; tambien se puede deshabilitar por configuracion con tesoreria_en_sync = false.

suvalor tesoreria se conserva como superficie opt-in de debug/manual para descargar movimientos de Tesoreria por rango explicito:

uv run suvalor tesoreria --from 2026-01-01 --to 2026-01-31 --format both --tag cuenta-corta
uv run suvalor tesoreria --from 2026-01-01 --to 2026-01-31 --format xls --redownload

Sigue aplicando el mismo limite de login manual: no se automatizan credenciales, teclado virtual, OTP ni reCAPTCHA. Si se usa --account, tambien se debe pasar un --tag seguro; el texto real de la cuenta nunca debe aparecer en rutas, logs ni resumenes.

El caso sin datos observado descarga un Movimientos_Tesoreria.xls de 44 bytes con solo encabezado y sin filas; el cliente lo reporta como sin movimientos/saltado y no crea archivos de exito falsos.

Funciones investigadas pero no automatizadas

  • Fondos: existe suvalor fondos para validar argumentos, rutas y scope, pero el flujo de pagina esta en modo fail-closed hasta contar con evidencia redacted suficiente de selectores, exportacion y sin-datos.
  • ReteFuente: la investigacion tecnica esta documentada en docs/SITE_NOTES.md; no hay comando suvalor retefuente ni integracion en sync porque el probe manual fue inconcluso.

Configuracion ($SUVALOR_HOME/_state/config.toml)

Opcional. Si no existe se usan defaults. Para crearlo:

uv run suvalor config init

Claves disponibles (con sus defaults):

retro_days = 60
range_days = 89                # NO subir, el sitio limita en 89 dias
retry_doc = 3
max_pages_per_query = 50
tipos_default = ["RC", "NC", "CE"]
tesoreria_en_sync = true
wait_min_consulta_s = 3.0
wait_min_descarga_s = 5.0
wait_min_page_change_s = 3.0

Memoria adaptativa de tiempos

El portal es lento y variable. En vez de hardcodear esperas, el cliente aprende cuanto tardan las operaciones y usa p95 + buffer como timeout con un piso configurable. Persistido en _state/timings.json con ventana movil de 50 mediciones.

uv run suvalor timings

Resiliencia

  • Verificacion post-descarga: PDFs validados por header (%PDF-), footer (%%EOF) y tamaño minimo. XLS-HTML validado por presencia de <table y ausencia de login/iniciar sesion. Archivos invalidos se borran y se reintenta.
  • Visor PDF inline (Adobe Acrobat ext): si Chrome tiene la extension de Adobe Acrobat instalada, los PDFs abren en visor (sin disparar download event). El cliente captura la pestaña popup, extrae la URL y descarga via context.request.get(url) reusando las cookies de sesion.
  • Sesion expirada: detectada por redirect a terminarSesion.aspx; el resumen lo refleja con indicador rojo.
  • Reintentos adaptativos: cada operacion reintenta hasta retry_doc veces (default 3). Solo las exitosas alimentan la memoria de tiempos.

Tests

uv run pytest

Suite pura de 284+ tests (sin Playwright, sin red). Cubre rangos, parseo, timings, formato de estado, heuristicas de verificacion, Tesoreria, Fondos fail-closed y argument parsing del CLI.

Estructura

suvalor/
├── pyproject.toml
├── README.md
├── LICENSE              (Apache-2.0)
├── NOTICE
├── DISCLAIMER.md        (lectura obligatoria)
├── AGENTS.md            (instrucciones para agentes IA)
├── CONTRIBUTING.md
├── .gitignore
├── docs/
│   └── SITE_NOTES.md    (hallazgos tecnicos del portal)
├── suvalor/             (paquete)
│   ├── __init__.py
│   ├── __main__.py
│   ├── cli.py           (entrypoint Typer)
│   ├── orquestador.py   (loop docs + extractos + cartera + tesoreria)
│   ├── navegador.py     (Playwright + perfil persistente + anti-deteccion)
│   ├── pagina.py        (interacciones ASP.NET)
│   ├── descargador.py   (descarga + popup PDF)
│   ├── verificacion.py  (post-descarga: PDF / XLS / reportes tabulares)
│   ├── estado.py        (inventario + extractos + ultima_corrida pydantic)
│   ├── timings.py       (memoria adaptativa de tiempos)
│   ├── rangos.py        (particion en rangos de 89 dias)
│   ├── parseo.py        (fechas + meses_es)
│   ├── config.py        (config.toml loader)
│   └── tipos.py         (constantes y enums; resuelve SUVALOR_HOME)
└── tests/

Decisiones de diseño

  • Typer + Rich: ecosistema unificado, --help legible, progress bars y tablas en corridas largas.
  • Pydantic v2 para state: validacion automatica, extra="allow" en RegistroCorrida para tolerar campos viejos no estandar.
  • Tenacity: usado de forma puntual; no se decora la cadena entera para preservar control fino sobre la deteccion de sesion expirada.
  • Loguru: dual log (DEBUG a archivo + INFO a consola) sin boilerplate.
  • Memoria adaptativa: ventana movil de 50, p95 recalculado en cada registro, timeout = max(piso, p95 + 2.5s, default). Conservador al inicio, se ajusta solo despues de 3 mediciones.

Hallazgos tecnicos del portal

Ver docs/SITE_NOTES.md: URLs, IDs ASP.NET, restricciones (89 dias por consulta, 12 meses de extractos, 504 en FB, Tesoreria sin movimientos, Fondos fail-closed, session timeout de 7 minutos).

Contribuir

Ver CONTRIBUTING.md. Resumen:

  1. Issue antes de PR (excepto fixes triviales).
  2. Conventional commits.
  3. Tests pasando: uv run pytest.
  4. Sin filtrar datos personales en commits o issues.

Para agentes IA

Ver AGENTS.md. Instrucciones especificas para que un agente (Claude Code, Cursor, Copilot, etc.) pueda instalar, configurar y trabajar con este cliente de forma segura.

Comunidad

Autor

John Alberto Parrado Gordillo (@jparradog)

Contribuciones de la comunidad bienvenidas — ver CONTRIBUTING.md.

Licencia

Apache License 2.0 — © 2026 John Alberto Parrado Gordillo.

Sujeto a los terminos de DISCLAIMER.md.

About

Cliente CLI no oficial para descarga incremental y verificada de documentos contables, extractos y cartera del portal Suvalor (Valores Bancolombia), usando tu propia sesion autenticada.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages