Ir al contenido principal

Presupuesto Abierto: seis años de scraping y un portal para periodistas

En mayo de 2020 consolidé una serie de scripts que venían procesando (desde hacía algunos años y con otros investigadores) la ejecución presupuestaria de la Provincia de Córdoba desde su portal de transparencia. Seis años después eso es FreeData: un portal con más de seis millones de comprobantes de pago, de 2016 a 2026, y más de medio millón de proveedores. Esta semana Ruido, la red de periodismo de investigación con la que trabajamos, lo presentó públicamente.

Portada de Presupuesto Abierto

El origen del dato

La Provincia publica cada comprobante que paga. Eso es mucho más de lo que publica la mayoría de los gobiernos argentinos y es bueno reconocerlo. El problema es cómo: un portal donde para llegar a un comprobante hay que elegir el año, después la jurisdicción, después el programa, el subprograma, la partida, y recién ahí aparece una lista paginada de a diez. No hay descarga, no hay API, no hay forma de preguntar "cuánto cobró este CUIT".

Portal de transparencia de la Provincia de Córdoba

Lo que hice fue recorrer ese árbol completo, año por año, nodo por nodo, guardando cada comprobante con sus items. Es scraping paciente: millones de pedidos durante alrededor de una decada, muchos reintentos y una base que crece de a poco. En 2026 la Provincia cambió el portal y hubo que reescribir todo el recolector contra la interfaz nueva.

El portal

Sobre esa base construimos desde cero una aplicación en Django con PostgreSQL. Lo principal:

  • Búsqueda por proveedor, CUIT, programa o partida, en toda la serie.
  • Montos originales y actualizados por inflación (gracias Sol Monoldo!), mes a mes, para que una compra de 2017 se pueda comparar con una de 2026.
  • Tiempos de cobro por proveedor: cuánto tarda el Estado en pagarle a cada uno.
  • Seguimiento: cualquier usuario puede seguir un proveedor y recibir avisos cuando aparecen comprobantes nuevos.
  • Notas de usuarios sobre proveedores, para que un periodista le ponga nombre conocido a una razón social.
  • Descarga en CSV de cualquier búsqueda, con los filtros aplicados.
  • Graficos, muchos gráficos por todos lados.
  • Descargas de CSV de tablas a la vista para seguir trabajando en la compu o cruzar datos por fuera.

Ficha de un proveedor en Presupuesto Abierto

Portal privado

Este es un portal cerrado. Se entra por invitación y con passkeys. Hoy lo usan periodistas y de a poco se va abriendo a investigadores y organizaciones.

¿Por qué?

La decisión de no abrirlo tiene varias razones (no necesariamente en este orden):

  • Alojar esta cantidad de datos y todas las posibilidad que da esta plataforma en un servidor require recursos que este proyecto no tiene. Nada de esto genera ingresos de ninguna forma lamentablemente. Hemos postulado a subsidios pero todavía no hemos tenido suerte. Acá podes donar a la Red Ruido
  • El trabajo realizado es muy grande, requiere validación que todo funcione como se espera. Estamos en etapa de pruebas.
  • Hay datos que consideramos que no es buena idea que sean públicos. Asumimos que los responsables de este portal son plenamente concientes de lo que publican pero aunque parezca extraño no coincidimos con semejante nivel de apertura. Sin dar ejemplos, hay datos que se refieren a situaciones personales de las personas que si bien como fondos publicos deben ser abiertos no es buena idea que se publiquen de forma indiscriminada. Por eso el portal es privado y con invitación a personas que lo van a usar responsablemente con fines perdiosticos y de investigación.
  • Porque si, porque despues de tanto trabajo esta bien ser discrecionales con el uso. Queremos que esto se use bien.

Algo de cocina

  • Django y PostgreSQL, sin frameworks de frontend. HTML plano y algo de JavaScript donde hace falta.
  • Dos servidores chicos: uno con un webserver y la aplicación detrás de Cloudflare y otro con la base de datos.
  • Cache, mucho cache en cada lugar que se pudo.
  • El recolector corre aparte: cada año tiene un porcentaje de cobertura que se controla con un informe de integridad para saber que falta
  • Autenticación con WebAuthn. Nadie tiene una contraseña que filtrar.
  • Respeto por el servidor del que obtenemos datos. Corremos muy lento, en general entre 20 y 40 requests por minuto.

Riesgos

En 2026 la Provincia cambió la interfaz gráfica y escondió muchos datos. Saco tambien las Agencias de Gobierno (Cultura, Deportes, etc). Muchos subprogramas ya no son visibles. ¿Que pasa si se apaga el portal? Esta plataforma puede seguir abierta aún si eso pasara y hoy mismo ya muestra más datos que el portal oficial por lo que se escodió en la última actualización.

Migrar dos portales de datos abiertos después de una década sin actualizar

Terminamos la migración de los dos portales de datos abiertos de la Provincia de Córdoba: datosgestionabierta.cba.gov.ar y datosestadistica.cba.gov.ar. Fue un año de trabajo, desde agosto de 2025 hasta agosto de 2026. Lo cuento porque es el tipo de proyecto que casi nunca se cuenta: no hay nada nuevo para inaugurar, hay algo viejo que dejó de ser un riesgo.

Portal de datos abiertos de la Provincia de Córdoba

El punto de partida

Los dos portales corrían sobre CKAN 2.6.2 con PostgreSQL 9.6, en servidores propios del gobierno. Esa versión de CKAN es de 2017. Nadie la había actualizado en casi diez años. Funcionaban pero cada día que pasaba la brecha con el CKAN actual se hacía más grande y el salto más caro.

Los que trabajamos con CKAN sabemos que una actualización de 2.6 a 2.11 no es una actualización menor. Cambió Python (de 2 a 3), cambió el framework web (de Pylons a Flask), cambió el esquema de la base y cambió la forma de escribir extensiones. Lo que había que hacer era construir portales nuevos y mover los datos.

Dos herramientas libres

Decidimos que todo lo que no fuera específico de Córdoba quedara publicado. Salieron dos repositorios:

ckan-to-aws despliega CKAN completo en AWS con Terraform y Docker: una tarea de ECS Fargate con CKAN, Solr y Redis, una base RDS PostgreSQL, imágenes en ECR, secretos en Secrets Manager y logs en CloudWatch. Un script, un .env y ya tenemos un CKAN andando.

ckan-migrator hace la migración a nivel base de datos. Levanta el dump viejo en un PostgreSQL 9.6 dockerizado, extrae cada tabla a CSV y JSON, y las inserta en el CKAN nuevo respetando el esquema actual. Datasets, recursos, organizaciones, grupos, usuarios y el historial de actividad. Los archivos subidos se mueven aparte.

Lo que sí es específico de Córdoba quedó en repositorios privados, uno por portal: una extensión para la interfaz de cada uno (los dos portales pertenecen a ministerios distintos y tienen identidad propia) y la configuración de cada ambiente. Cada equipo del gobierno tiene su repo y puede gestionar sus diferencias sin tocar la base común.

Portal de la Dirección de Estadísticas y Censos

Conjuntos de datos del portal

Lo que queda

Todo el proceso fue documentado exaustivamente para que cualquier equipo técnico pueda actualizar CKAN en el futuro sin depender de un proveedor externo. La migración de datos es reproducible y los portales pueden ser desplegados en cualquier nube o servidor propio.

Un portal de datos abiertos para la Universidad Nacional de Córdoba

La Universidad Nacional de Córdoba tiene portal de datos abiertos: datosabiertos.unc.edu.ar. Lo hicimos desde cero sobre CKAN 2.11 y es de los trabajos que más disfruté en los últimos años, así que va un poco de detalle.

Portada del portal de datos abiertos de la UNC

De dónde viene

La idea de un CKAN para universidades la venimos planeando desde 2019 con el equipo de la UNC. De aquella época quedaron en GitHub un cosechador para los sistemas SIU (los que usan casi todas las universidades públicas argentinas), una librería para sacar datos de ahí y otra para conectarse a la API de SIGEVA de CONICET. Eran experimentos. El portal de verdad arrancó a fines de 2024, cuando se redefinió mejor como extraer datos y publicar.

De donde vienen los datos?

La UNC hizo un gran trabajo sobre Apache Superset, que es la herramienta de visualización de datos que usan para sus tableros internos. La idea fue conectar CKAN con Superset y publicar como datasets lo que ya estaba en los tableros. Para eso hicimos la extensión ckanext-superset. No había otra extensión que hiciera esto asi que la dejamos abiertas para poder ser reutilizada por otros.

Qué quedó publicado

Todo lo que no es específico de la UNC vive en la organización UnCKAN en GitHub, pensando en que otra universidad pueda reutilizarlo:

  • ckanext-superset: conecta CKAN con Apache Superset para publicar como datasets lo que ya está en los tableros de la universidad.
  • ckanext-dbquery: consultas a la base desde el propio CKAN, para los administradores y solo para casos especiales. En muchos casos los administradores de CKAN no tienen acceso a la base de datos y esta extensión permite hacer consultas SQL desde la interfaz web.
  • ckanext-push-errors: cuando algo se rompe en producción, el error llega a Slack antes de que alguien lo reporte.
  • ckan-env: el entorno Docker completo para levantar el portal en cualquier máquina. Esto es solo para entorno de desarrollo local. Hay un repositorio privado con la configuración de producción que gestiona el equipo de la UNC.
  • ckanext-citeproc: hicimos un fork de esta extensión y la adaptamos para que funcione en nuestro caso. Esta extensión permite citar datasets en formato APA, Chicago y MLA.

Conjuntos de datos del portal de la UNC

Otras universidades

Todo esto fue hecho pensando que otras universidades puedan reutilizarlo. La idea es que cada universidad pueda tener su propio portal de datos abiertos, con su identidad y sus datasets, pero usando la misma base común. Solo sería necesario que cada universidad conecte una instancia de Apache Superset con sus propios datos (usalmente de los sistemas SIU) y haga una extension de interfaz gráfica adaptada a su caso. El resto es común y puede ser reutilizado tal cual.