Skip to main content

FiscalPY

fiscalpy es un paquete de Python para facilitar la extracción, limpieza y análisis de datos fiscales y administrativos de Colombia.

Actualmente incluye herramientas para:

  • limpiar datos del Presupuesto General de la Nación (PGN);
  • limpiar y clasificar información de finanzas territoriales;
  • descargar datos de datos.gov.co mediante la API de Socrata;
  • generar reportes estandarizados de contratación pública a partir de datos de SECOP II.

Instalación

pip install fiscalpy

Para trabajar con la versión local del repositorio durante el desarrollo:

pip install -e .

¿Cómo usarla?

Presupuesto nacional

Para la limpieza del presupuesto nacional se cuenta con las funciones limpieza_gastos_pgn y limpieza_ingresos_pgn.

Los datos deben provenir directamente de los archivos publicados por el Ministerio de Hacienda y Crédito Público de Colombia, y la primera fila del archivo debe contener los nombres de las columnas.

import pandas as pd
from fiscalpy import limpieza_gastos_pgn, limpieza_ingresos_pgn

gastos = pd.read_excel("gastos.xlsx")
rentas = pd.read_excel("rentas.xlsx")

gastos_limpios = limpieza_gastos_pgn(gastos)
rentas_limpias = limpieza_ingresos_pgn(rentas)

El resultado son DataFrame normalizados y preparados para análisis estadístico y gráfico.

Finanzas territoriales

Para información territorial se incluyen las funciones:

  • limpieza_ingresos_territoriales
  • limpieza_gastos_territoriales
  • columnas_ingresos_territoriales

Las dos primeras permiten normalizar datos de ingresos y gastos territoriales, tanto de ejecución como de programación.

import pandas as pd
from fiscalpy import limpieza_ingresos_territoriales

df = pd.read_excel("datos_ejecucion_2025.xlsx")

norm_data = limpieza_ingresos_territoriales(
    df,
    tipo="ejecucion",
)

En el argumento tipo se debe indicar si se trabaja con datos de "ejecucion" o de "programacion".

La función columnas_ingresos_territoriales agrega columnas de clasificación que permiten agrupar los ingresos territoriales con distintos niveles de detalle. Entre las agrupaciones disponibles se encuentran:

  • recursos propios, transferencias y recursos de capital;
  • ingresos tributarios, ingresos no tributarios, transferencias y recursos de capital;
  • principales fuentes de ingreso relevantes para municipios y departamentos.

Extracción de datos abiertos

datos_abiertos

La función datos_abiertos descarga información directamente desde datos.gov.co utilizando la API de Socrata y devuelve el resultado como un pandas.DataFrame.

from fiscalpy import datos_abiertos

La función recibe el identificador Socrata del conjunto de datos, un token de aplicación y, opcionalmente, filtros para limitar la consulta.

from datetime import date
from fiscalpy import datos_abiertos

filtros = {
    "nit_entidad": {"in": ["900948953"]},
    "fecha_de_firma": {
        "gte": date(2022, 1, 1),
        "lt": date(2023, 1, 1),
    },
}

df = datos_abiertos(
    dataset_id="jbjy-vk9h",
    token="TU_TOKEN_SOCRATA",
    filtros=filtros,
)

En este ejemplo se consulta el dataset identificado por jbjy-vk9h y se conservan únicamente los registros que cumplen los filtros especificados.

Filtros simples

Para una igualdad se puede pasar directamente el valor:

df = datos_abiertos(
    dataset_id="jbjy-vk9h",
    token="TU_TOKEN_SOCRATA",
    filtros={"estado_contrato": "En ejecución"},
)

Una lista se interpreta como una condición IN:

filtros = {
    "estado_contrato": ["En ejecución", "Terminado"]
}

También es posible suministrar filtros simples como argumentos adicionales:

df = datos_abiertos(
    "jbjy-vk9h",
    "TU_TOKEN_SOCRATA",
    nit_entidad="900948953",
)

Filtros avanzados

Los operadores disponibles son:

Operador Condición SoQL
eq =
ne !=
gt >
gte >=
lt <
lte <=
in IN (...)
not_in NOT IN (...)
between BETWEEN ... AND ...
not_between NOT BETWEEN ... AND ...
like LIKE
not_like NOT LIKE
is_null IS NULL
not_null IS NOT NULL

Por ejemplo:

filtros = {
    "valor_del_contrato": {"gte": 100_000_000},
    "fecha_de_firma": {
        "between": [date(2024, 1, 1), date(2024, 12, 31)]
    },
    "estado_contrato": {"not_in": ["Borrador"]},
}

La función pagina automáticamente las consultas en bloques de hasta 50.000 registros, por lo que puede descargar resultados que superen ese límite sin que el usuario tenga que manejar manualmente los offset de la API.

Para consultas frecuentes o de mayor tamaño se recomienda utilizar un token de aplicación de Socrata.

Reportes

reporte_contratacion

reporte_contratacion genera un reporte descriptivo de contratación pública a partir de un DataFrame de contratos y una tabla de IPC.

from fiscalpy import reporte_contratacion

La función prepara los datos, expresa los valores monetarios en precios constantes, construye tablas de análisis y, opcionalmente, exporta un archivo Excel y gráficos en formato SVG.

Un flujo típico consiste en descargar primero los contratos con datos_abiertos y luego generar el reporte:

import pandas as pd
from fiscalpy import datos_abiertos, reporte_contratacion

contratos = datos_abiertos(
    dataset_id="jbjy-vk9h",
    token="TU_TOKEN_SOCRATA",
    filtros={
        "nit_entidad": "900948953",
    },
)

ipc = pd.read_excel("datos_macro.xlsx")

resultado = reporte_contratacion(
    contratos,
    ipc,
    salida="salidas_contratacion",
    anio_base=2026,
    crecimiento_ipc_base=0.069,
    verbose=True,
)

Datos requeridos

El DataFrame de contratación debe contener, como mínimo, las siguientes columnas:

id_contrato
fecha_de_firma
valor_del_contrato
duraci_n_del_contrato
dias_adicionados
proveedor_adjudicado
tipo_de_contrato
modalidad_de_contratacion
estado_contrato

Estos nombres corresponden a la estructura utilizada por los datos de contratos electrónicos de SECOP II en datos.gov.co.

La tabla de IPC debe ser un DataFrame con las columnas:

Año
IPC

Por ejemplo:

ipc.head()
    Año      IPC
0  2022   120.27
1  2023   131.35
2  2024   140.12
3  2025   152.27

Año base y precios constantes

El argumento anio_base determina el año al que se llevan todos los valores monetarios.

resultado = reporte_contratacion(
    contratos,
    ipc,
    salida="salidas_contratacion",
    anio_base=2026,
    crecimiento_ipc_base=0.069,
)

Si el IPC del año base ya se encuentra en la tabla de IPC, la función lo utiliza directamente. Si todavía no está disponible, crecimiento_ipc_base permite construirlo a partir del IPC del año inmediatamente anterior.

Por ejemplo, 0.069 representa un crecimiento de 6,9 %.

Archivos generados

Por defecto se crea una estructura similar a:

salidas_contratacion/
├── tablas_analisis_contratacion.xlsx
└── graficos_svg/
    ├── 01_contratos_anio.svg
    ├── 02_monto_anio.svg
    ├── 03_promedio_anio.svg
    ├── ...
    └── 15_dias_adicionados.svg

El archivo Excel contiene tablas sobre, entre otros temas:

  • número y monto de contratos por año y mes;
  • rangos de monto diario;
  • monto diario ajustado por días adicionados;
  • proveedores con mayores montos y mayor número de contratos;
  • tipos y modalidades de contratación;
  • estado de los contratos;
  • distribución de días adicionados;
  • contratos con montos diarios elevados;
  • contratos con más de 100 días adicionados.

Los gráficos se exportan como SVG para conservar elementos vectoriales y texto editable. Si se requiere una copia en PNG, se puede utilizar:

resultado = reporte_contratacion(
    contratos,
    ipc,
    salida="salidas_contratacion",
    exportar_png=True,
)

Resultado en Python

Además de escribir archivos, la función devuelve un diccionario con los resultados del análisis:

resultado.keys()
dict_keys(['datos', 'ipc', 'tablas', 'graficos', 'excel', 'metadata'])

Los principales componentes son:

  • resultado["datos"]: base de contratación preparada y enriquecida;
  • resultado["ipc"]: tabla de IPC utilizada en el cálculo;
  • resultado["tablas"]: diccionario con todas las tablas analíticas;
  • resultado["graficos"]: rutas de los gráficos generados;
  • resultado["excel"]: ruta del archivo Excel generado;
  • resultado["metadata"]: información general del reporte.

Por ejemplo, las tablas pueden consultarse directamente sin abrir el Excel:

resultado["tablas"]["resumen_general"]
resultado["tablas"]["por_anio"]
resultado["tablas"]["proveedores"]
resultado["tablas"]["contratos_mas_100_dias"]

Opciones de exportación

La generación de archivos puede controlarse con los siguientes argumentos:

resultado = reporte_contratacion(
    contratos,
    ipc,
    salida="salidas_contratacion",
    exportar_excel=True,
    exportar_graficos=True,
    exportar_png=False,
)

Esto permite utilizar reporte_contratacion tanto como generador de entregables como dentro de otros flujos de análisis en Python.

Reporte de ejecución presupuestal

reporte_ejecucion permite homologar la ejecución presupuestal del año corriente con la serie histórica y generar un conjunto estandarizado de gráficos de ejecución del PGN.

Ejemplo

import pandas as pd
from fiscalpy import reporte_ejecucion

historico = pd.read_excel(
    "ejecucion_2019_2025.xlsx"
)

actual = pd.read_excel(
    "ejecucion_2026.xlsx",
    sheet_name="Vigencia",
    skiprows=3,
)

macro = pd.read_csv(
    "datos_macro.csv"
)

resultado = reporte_ejecucion(
    historico=historico,
    actual=actual,
    macro=macro,
    salida="salidas_ejecucion",
    entidades=[4106, 4602],
    anio_actual=2026,
    mes_corte="agosto",
)

## Licencia

Este proyecto se distribuye bajo la licencia incluida en el repositorio.

Metadata

Release files for fiscalpy 0.0.22

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fiscalpy 0.0.22
File Size Uploaded
fiscalpy-0.0.22.tar.gz 42.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fiscalpy 0.0.22
File Interpreter ABI Platform
fiscalpy-0.0.22-py3-none-any.whl Python 3 none any Details

Total release size: 81.8 kB

Release files / fiscalpy-0.0.22.tar.gz

Download URL fiscalpy-0.0.22.tar.gz
Size 42.0 kB
Tags Source
SHA-256 checksum
How to use checksums
8a20574c015011d2807c81024207d7d83056132645d2c4a51fe14f1c56b869d4
BLAKE2b-256 checksum
How to use checksums
b7c2202ccb7008089c392740ab94d254e94de5a4497e639da4f5ee01930ce830
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.7

Release files / fiscalpy-0.0.22-py3-none-any.whl

Download URL fiscalpy-0.0.22-py3-none-any.whl
Size 39.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e9b84477f8a3dc62c393ad4c8d8f7ca038213b6b00d1397797a2a7645cf1e970
BLAKE2b-256 checksum
How to use checksums
e0fe1e8f028c1a9643452b7c6c5cf460039c3b563103b68883721f6fac633055
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

0.0.22 This release

2 release files

0.0.21

2 release files

0.0.20

2 release files

0.0.19

2 release files

0.0.18

2 release files

0.0.17

2 release files

0.0.16

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page