Sinergox es un cliente asíncrono para consultar la API pública de XM (https://sinergox.xm.com.co/Paginas/Home.aspx) y obtener los datos en formato tidy listo para análisis con pandas. El paquete proporciona utilidades para descubrir métricas disponibles, descargar series de tiempo en diferentes resoluciones (horaria, diaria, mensual y anual) y trabajar con un catálogo de entidades predefinidas.
- Python 3.10 o superior.
- Dependencias gestionadas con
uv(recomendado) opip. - Conexión a Internet hacia
https://servapibi.xm.com.co. - Los ejemplos usan la zona horaria oficial de Colombia (
America/Bogota) a través del módulo estándarzoneinfo.
Instala la versión publicada en GitHub agregando el paquete a tu entorno:
uv add sinergoxSi prefieres pip:
pip install sinergoximport asyncio
from sinergox import Client
async def main() -> None:
async with Client() as client:
# Descarga los últimos siete días para la primera métrica que coincida
# con la consulta, asumiendo la zona horaria de Bogotá.
datos = await client.get_data_for(
"volumen util",
)
print(datos.head())
if __name__ == "__main__":
asyncio.run(main())Todas las funciones públicas del Client son asíncronas; ejecútalas dentro de
una corrutina async y usa await, o encapsula la llamada con asyncio.run.
La API incluye un catálogo con más de 150 métricas. Usa client.find_metric
para obtener coincidencias directas y homogéneas, o client.search_metrics
datos = await client.get_data_for(
"VoluUtil",
timezone=zona,
start=dt.datetime(2025, 11, 1, tzinfo=zona),
end=dt.datetime(2025, 11, 3, tzinfo=zona),
)
La búsqueda normaliza acentos y diacríticos, y combina coincidencias exactas
con similitud difusa.
## Obtención de datos
`client.get_data` descarga la serie en la granularidad indicada por `TimeResolution`
y devuelve un `DataFrame` indexado por `MetricName` y `Timestamp`. El cliente
divide automáticamente los rangos extensos en ventanas compatibles con la API
para evitar errores por límite de días. Si no indicas la zona horaria, las fechas
y horas se asumen en `America/Bogota` antes de convertirlas a UTC. Puedes controlar
el paralelismo con el parámetro `concurrency`.
```python
from zoneinfo import ZoneInfo
zona = ZoneInfo("America/Bogota")
datos_horarios = await client.get_data(
TimeResolution.HORARIO,
metric="DemaReal",
entity=Entity.SISTEMA,
start=dt.datetime.now(zona) - dt.timedelta(days=7),
end=dt.datetime.now(zona) - dt.timedelta(days=1),
)
Para obtener datos sin revisar manualmente el catálogo, usa
client.get_data_for. La función toma la primera coincidencia de
find_metric, convierte automáticamente la columna Entity al Entity
correspondiente y, si no indicas un rango temporal, descarga los últimos
siete días por defecto.
import datetime as dt
from zoneinfo import ZoneInfo
from sinergox import Entity
zona = ZoneInfo("America/Bogota")
datos = await client.get_data_for(
"VoluUtil",
entity=Entity.EMBALSE,
timezone=zona,
start=dt.datetime(2025, 11, 1, tzinfo=zona),
end=dt.datetime(2025, 11, 3, tzinfo=zona),
)Puedes ajustar la zona horaria, definir explícitamente start y end, fijar
un TimeResolution específico o restringir la búsqueda a una entidad concreta
mediante los argumentos opcionales.
El catálogo se mantiene en memoria y se refresca automáticamente cada hora. Si
necesitas un TTL distinto (o desactivar la expiración) configura el parámetro
metrics_cache_ttl al crear el cliente:
client = Client(metrics_cache_ttl=dt.timedelta(hours=6))Para forzar una actualización manual usa await client.get_metrics(force_refresh=True).
Ejecuta la suite unitaria con:
uv run --group dev pytestLas pruebas de integración dependen del servicio en vivo. Habilítalas
exportando la variable de entorno RUN_INTEGRATION_TESTS:
$Env:RUN_INTEGRATION_TESTS = "1"
uv run --group dev pytest -m integration -rsTen en cuenta que las pruebas omiten cualquier fallo externo (HTTP 4xx/5xx)
mediante pytest.skip para no interrumpir tu flujo de trabajo.