---
title: "Cliente Python para la API de Wialon que funciona"
url: https://theassettrack.com/es/blog/wialon-api-python-client/
description: "Un cliente Python moderno para la Remote API de Wialon: login, búsqueda, eventos en vivo con avl_evts, y qué librerías siguen vivas y cuáles murieron."
---

# Cliente Python para la API de Wialon que funciona

[Siarhei Havarunou](https://www.linkedin.com/in/sergey-govorunov/) – CEO

11 de septiembre de 2026 · Actualizado 10 de octubre de 2026

Un cliente Python moderno para la Remote API de Wialon: login, búsqueda, eventos en vivo con avl_evts, y qué librerías siguen vivas y cuáles murieron.

Cada pocos meses alguien pregunta qué librería de Python usar con Wialon. La respuesta honesta es incómoda: las dos librerías con los nombres más reconocibles — `python-wialon` y `php-wialon`, en la organización wialon de GitHub — no se tocan desde aproximadamente 2013. Todavía funcionan para llamadas básicas, pero son anteriores a la mitad de la superficie de la API y a todo el conocimiento operativo. Esta guía le da un cliente mínimo que usted controla, en unas setenta líneas; después, los cinco comportamientos que deciden si sobrevive al contacto con una cuenta real; y por último un mapa honesto del panorama de librerías.

## El protocolo, para que el cliente tenga sentido

Wialon usa POST con formularios codificados, no REST con JSON: cada llamada va a `wialon/ajax.html` con un campo `svc` que nombra el servicio, un campo `params` con JSON y un campo `sid` una vez que tiene sesión. No hay rutas, ni verbos, ni códigos de estado que leer — un HTTP 200 con `{"error":7}` en el cuerpo es la forma en que llega la denegación de acceso. (La mecánica completa está en la [página de configuración de Postman](https://theassettrack.com/wialon-api/postman/).) Ese es todo el protocolo, y por eso un wrapper es un objeto de sesión alrededor de `requests` y nada más.

`import requests class Wialon: def __init__ (self, host = "https://hst-api.wialon.com", token = None): self.host = host self.base = host + "/wialon/ajax.html" self.sid = None self.token = token def call (self, svc, params = None, sid = True): data = { "svc": svc, "params": params or {}} if sid: data[ "sid" ] = self.sid r = requests.post(self.base, data = data, timeout = 30) r.raise_for_status() return r.json() def login (self): res = self.call("token/login", { "token": self.token}, sid = False) if "error" in res: raise RuntimeError (f "login failed: { res } ") self.sid = res[ "eid" ] return self.sid def events (self): # avl_evts is its own path, not an svc against ajax.html. r = requests.post(f " {self.host } /avl_evts", data = { "sid": self.sid}, timeout = 30) r.raise_for_status() return r.json()`

Setenta líneas es una ventaja, no una limitación: no hay magia que depurar a las 3 a. m. cuando una sincronización se traba. Genere el token en la interfaz de Wialon con los flags de acceso más estrechos que cubran sus lecturas — la [página del token](https://theassettrack.com/wialon-api/token/) tiene la tabla de flags — y manténgalo fuera del código, en una variable de entorno.

## Con qué host está hablando realmente

`hst-api.wialon.com` es el endpoint de Hosting, y es el valor por defecto correcto solo si su cuenta vive en Wialon Hosting. Una instalación de Wialon Local responde en el dominio propio del partner, y un token generado contra un host no significa nada contra el otro — la sesión la emite el servidor que tiene la cuenta. Por eso `host` es un argumento del constructor más arriba y no una constante del módulo: el día que sume un segundo cliente en otro despliegue, lo único que debería cambiar es el valor que pasa.

Vale la pena nombrar desde ya dos errores relacionados. El primero es dejar `hst-api.wialon.com` fijo en un cliente que piensa vender a partners, lo que limita sin avisar su producto a un solo despliegue. El segundo es tratar el host de la interfaz y el host de la API como la misma cadena; están relacionados pero no son intercambiables, y copiar una URL del navegador a la configuración del cliente produce un 404 que parece una falla de red.

## Primero buscar, después mensajes

Dos llamadas cargan con la mayoría de las integraciones. `core/search_items` encuentra cosas; `messages/load_interval` lee su historial:

`w = Wialon(token = "...") w.login() units = w.call("core/search_items", { "spec": { "itemsType": "avl_unit", "propName": "sys_name", "propValueMask": "*", "sortType": "sys_name", }, "force": 1, "flags": 1, "from": 0, "to": 0, }) unit_id = units[ "items" ][ 0 ][ "id" ] msgs = w.call("messages/load_interval", { "itemId": unit_id, "timeFrom": 1726000000, "timeTo": 1726086400, "flags": 0, "flagsMask": 0x FF00, "loadCount": 10000, })`

Cuatro detalles de esa primera llamada deciden lo que obtiene. `itemsType` elige el catálogo: `avl_unit` para unidades, `avl_resource` para recursos, `avl_unit_group` para grupos, `user` para usuarios. `propName` y `propValueMask` son el filtro, y `sys_name` con `*` es la expresión idiomática para “todo lo que tengo permiso de ver”. `sortType` le da un orden estable, que importa más de lo que parece: sin él, al paginar una cuenta grande puede ver la misma unidad dos veces y perderse otra. Y `flags` no es un booleano sino una máscara de bits de data-flags: `1` devuelve el conjunto base (id, nombre, clase, unidades de medida), mientras que sensores, contadores y última posición son bits aparte, cada uno con costo en el tamaño de la respuesta. La [referencia de unidades](https://theassettrack.com/wialon-api/units/) trae la tabla completa; la regla a interiorizar es pedir la máscara más estrecha que responda su pregunta, porque en una cuenta de tres mil unidades la diferencia entre el flag `1` y una máscara codiciosa se mide en megabytes por consulta.

La paginación es lo segundo que hay que hacer bien. `from` y `to` son índices de fila, no marcas de tiempo, y la respuesta le dice dónde está: `totalItemsCount` junto con `indexFrom` e `indexTo`. Pedir de `0` a `0` devuelve una sola fila, lo cual sirve para el ejemplo de arriba y es incorrecto para producción; recorra el índice en bloques de unos cientos y deténgase cuando `indexTo` llegue a `totalItemsCount`.

Dos trampas viven en la segunda llamada. Primero, `flagsMask` selecciona qué tipos de mensaje vuelven y `flags` indica cuáles de ellos quiere: el par documentado para mensajes de datos es la máscara `0xFF00` con flags `0x0000`, y pedir todo en una unidad activa devuelve megabytes que no quería. Segundo, `loadCount` limita el lote: itere avanzando `timeFrom` en lugar de subirlo, o una sola unidad longeva superará el [presupuesto de cinco minutos de los reportes](https://theassettrack.com/wialon-api/reports/) y le devolverá cero filas que parecen una semana tranquila.

## Eventos en vivo sin matarse a polling

Para casi tiempo real, no consulte `load_interval` con un temporizador. Suscriba la sesión con `core/update_data_flags` y luego haga polling de `avl_evts`, el canal de eventos propio de Wialon. Atención a la dirección: `avl_evts` no es un `svc` contra `wialon/ajax.html` sino una ruta propia, `{host}/avl_evts?sid=<sid>`, y por eso el cliente necesita el segundo método de arriba en lugar de otro `call()`:

`import time w.call("core/update_data_flags", { "spec": [{ "type": "type", "data": "avl_unit", "flags": 1, "mode": 0 }], }) while True: for e in w.events().get("events", []): handle(e) # your code: queue it, do not process inline time.sleep(1)`

Conviene leer con atención la entrada de `spec`. `type` dice cómo selecciona los elementos: `"type"` suscribe a una clase entera, y la alternativa selecciona una colección específica de ids, que es lo que querrá cuando la cuenta sea tan grande que “todas las unidades” sea más de lo que necesita. `flags` es la misma máscara de data-flags de la búsqueda, así que los eventos que recibe traen solo los campos que pidió. `mode` `0` reemplaza lo que tuviera suscrito la sesión, lo que convierte la resuscripción tras una reconexión en una única llamada idempotente y no en una diferencia que usted deba calcular.

Cada evento trae un id de elemento, un tipo y una carga útil: un mensaje nuevo, una actualización del elemento, una eliminación. La respuesta incluye además el reloj del propio servidor, y usarlo en lugar del reloj de su proceso elimina toda una clase de bugs de “el evento llegó antes de ocurrir” en máquinas con la hora desfasada.

Dos límites, ambos publicados, dan forma a este bucle: no más de 10 solicitudes a `avl_evts` cada 10 segundos por sesión, y diez solicitudes simultáneas a la API por sesión en total. Un bucle de un segundo ya gasta todo el presupuesto de eventos, así que esta sesión no debería hacer nada más — ejecute las extracciones en una segunda sesión. Y el bucle de arriba es delgado a propósito: mueve los eventos a una cola y vuelve al polling. Procesar en línea es la manera en que las integraciones se atrasan en las horas pico y luego golpean la API al ponerse al día, que es justamente el modo de falla del que trata el artículo sobre [diseño de sync resiliente](https://theassettrack.com/blog/wialon-api-rate-limits-and-resilient-sync-design/). Si necesita push de verdad en lugar de polling, lea [por qué Wialon no tiene webhooks](https://theassettrack.com/es/blog/wialon-webhooks-vs-polling/) antes de diseñar la arquitectura alrededor de esa ausencia.

## La sesión muere en silencio, con reloj

Una sesión de Wialon no es un bearer token de larga vida. Se cierra tras cinco minutos sin solicitudes, lo que significa que una integración que ejecuta un trabajo por hora tiene una sesión muerta cincuenta y cinco minutos de cada sesenta y lo descubre en el peor momento. El bucle de eventos de arriba nunca lo nota, porque hace polling cada segundo; un lote nocturno lo nota todas las noches.

Hay tres defensas y conviene tener las tres. Mantenga la sesión activa si el proceso es longevo: cualquier llamada barata dentro de la ventana sirve, y `avl_evts` es la convencional porque además es lo que ya estaba consultando. Trate el error `1` como una instrucción de volver a iniciar sesión exactamente una vez y repetir la llamada, nunca como algo para reintentar en un bucle. Y renueve el token mismo bien dentro de la regla de cien días de inactividad descrita en la [página del token](https://theassettrack.com/wialon-api/token/), porque una sesión expirada y un token eliminado aparecen ambos como error `1` pero requieren arreglos completamente distintos.

El patrón que falla en producción es la sesión compartida de larga vida: un login al iniciar el proceso, un `sid` entregado a todos los workers y ningún camino de reautenticación. Funciona hasta el primer corte de red, y entonces todos los workers fallan a la vez con el mismo código sin que nada en su aplicación haya cambiado para explicarlo.

## Errores, clasificados antes de reintentar

Wialon devuelve los errores como un HTTP 200 con un código en el cuerpo, así que su cliente debe buscarlos explícitamente — `raise_for_status()` nunca se disparará. Los códigos caen en cuatro grupos, y el grupo decide el comportamiento:

| Códigos | Clase | Qué debe hacer el cliente |
| --- | --- | --- |
| 1, 1011 | Sesión perdida | Volver a iniciar sesión una vez, repetir la llamada una vez, y luego rendirse |
| 4 | Entrada inválida | No reintentar: es un bug en sus parámetros |
| 7 | Acceso denegado | No reintentar: al token le falta un flag, o el elemento no es suyo |
| 10 | Límite de concurrencia | Esperar y reintentar; superó el tope por sesión |
| 1001 | Sin mensajes en el intervalo | No es un error: es un resultado vacío para esa ventana |
| 1005 | Tiempo de ejecución excedido | Dividir el intervalo y probar las mitades |

La distinción que más tiempo ahorra es la que separa el `4` del `7`. El error `4` significa que la solicitud estaba mal formada para el servicio: un campo faltante, una cadena donde va un número, un id que no se puede interpretar. El error `7` significa que la solicitud estaba bien formada y usted no tiene permiso para hacerla, lo que casi siempre se debe a los flags de acceso del token y no a algo del elemento. Reintentar cualquiera de los dos es puro desperdicio, y reintentar el error `1` en un bucle es la forma de que bloqueen una dirección de salida. La [referencia de errores](https://theassettrack.com/wialon-api/errors/) trae la tabla completa y las cadenas de motivo que califican los códigos.

## Una solicitud en lugar de cuarenta

Cuando necesita la misma llamada para muchos elementos — leer un contador en cada unidad, actualizar un campo en toda una flota — `core/batch` las envía juntas:

`res = w.call("core/batch", { "params": [ { "svc": "core/search_item", "params": { "id": uid, "flags": 1 }} for uid in unit_ids ], "flags": 0, })`

`flags` `0` ejecuta todos los comandos sin importar las fallas y devuelve un resultado por comando; `flags` `1` se detiene en el primer error, tras lo cual los comandos restantes devuelven el error `10`. Prefiera `0` para lecturas, de modo que un id malo no le cueste los otros treinta y nueve resultados, y `1` para escrituras que no deben aplicarse a medias.

Agrupar también es el arreglo más barato para el tope de concurrencia que sigue: cuarenta llamadas en una solicitud ocupan un lugar, no cuarenta.

## La concurrencia pertenece a la sesión, no a su pool

Tres límites publicados gobiernan cuánto puede empujar, y los tres son por sesión, no por cuenta ni por IP: diez solicitudes simultáneas a la API, tres solicitudes pesadas simultáneas (la carga de mensajes y la ejecución de reportes son los ejemplos que da la documentación) y los diez `avl_evts` cada diez segundos ya mencionados. Un pool de veinte hilos que comparten una sesión no va el doble de rápido que uno de diez: empieza a recolectar el error `10`.

La forma que funciona es una sesión por worker, con un token por worker y no un token por ejecución. Los tokens tienen un tope por usuario, así que generar uno nuevo en cada ejecución termina agotando el cupo y el trabajo empieza a fallar incluso al autenticarse. Y mantenga el bucle de eventos en una sesión propia: es barato, es constante, y compartirlo con una extracción es la manera de que un backfill nocturno deje sin recursos su feed en tiempo real.

## Qué registrar, desde el primer día

Cuatro campos hacen tratable cualquier incidente posterior: el nombre del servicio, los milisegundos transcurridos, el código de error si lo hay y los límites del intervalo para cualquier cosa que lea historial. Agregue una huella corta del id de sesión — nunca el id en sí — y podrá distinguir “la sesión murió” de “la llamada estaba mal” con una búsqueda en los logs y no con una sesión de depuración. Lo único que no debe registrar es el token.

## El panorama de librerías, mapeado con honestidad

- **`python-wialon` / `php-wialon` (organización wialon, ~2013).** Nombres reconocibles, proyectos muertos. Sirven como referencia de la forma de las llamadas, no como dependencias.
- **`py-aiowialon`, `wialon`, `wialon-sdk` (PyPI, de terceros).** Wrappers asíncronos o de conveniencia, de vigencia variable. Bien para scripts; audite el manejo de sesión antes de confiarle a uno la sincronización de producción: la renovación del token y el re-login ante el error 1/4 es donde suelen recortar.
- **Sus propias setenta líneas (arriba).** Lo que nosotros corremos en producción detrás de una cola. Usted es dueño de la política de reintentos, el backoff y el registro, que son las partes que de verdad se rompen.

El patrón en las tres: el HTTP es trivial, la operación no. Las sesiones expiran, los tokens se revocan tras 100 días de inactividad, las llamadas pesadas se limitan a tres a la vez por sesión. Quien sea dueño de su código de cliente es dueño de esos comportamientos: asegúrese de que sea usted, no un paquete abandonado.

## Qué sigue

Con un cliente y una cola en mano, las siguientes preguntas son de arquitectura: [una sincronización que sobreviva a los límites de tasa](https://theassettrack.com/blog/wialon-api-rate-limits-and-resilient-sync-design/), [llevar los datos a PostgreSQL](https://theassettrack.com/blog/wialon-to-postgresql-production-pipeline/) y [empujarlos después hacia un ERP](https://theassettrack.com/es/blog/wialon-integration-with-erp-architecture-and-pitfalls/). Si esa cola empieza a parecer un producto y no un script, eso es lo que construye nuestra [práctica de integración](https://theassettrack.com/es/wialon-integration/).

Trabaje con nosotros

¿Necesita esto funcionando en su propio Wialon?

Construimos integraciones de Wialon, canalizaciones de datos y aplicaciones de flota marca blanca. Veinte minutos de llamada suelen bastar para decir si su caso es una semana de trabajo o un trimestre.

[Book a free call](https://cal.com/sergey.govorunov/call) o escríbanos

## Más de Asset Track

- 11 de septiembre de 2026 · Estrategia
 ### Cómo ser partner de Wialon (2026)
 El modelo de partner de Wialon explicado: planes de facturación y margen, de dónde vienen los leads, estados y dónde se traban los nuevos partners.
 [Cómo ser partner de Wialon (2026)](https://theassettrack.com/es/blog/how-to-become-wialon-partner/)
- 11 de septiembre de 2026 · Estrategia
 ### Precios de Wialon: Hosting, Local, Platform, Lite
 Cómo funcionan los precios de Wialon en sus cuatro ediciones — Hosting, Local, Platform y Lite: planes, descuentos y las cinco variables de la factura.
 [Precios de Wialon: Hosting, Local, Platform, Lite](https://theassettrack.com/es/blog/wialon-pricing-hosting-explained/)
- 11 de septiembre de 2026 · Integración
 ### Wialon no tiene webhooks: así se hace polling
 Wialon no puede enviar eventos a su URL. Tres alternativas que funcionan: polling de avl_evts, acciones de notificación y un puente con flespi.
 [Wialon no tiene webhooks: así se hace polling](https://theassettrack.com/es/blog/wialon-webhooks-vs-polling/)
- Actualizado 9 de septiembre de 2026 · Analítica
 ### Límites de los informes de Wialon y analítica en SQL
 Cuando los informes de Wialon se quedan cortos, la analítica en SQL abre dimensiones propias, comparaciones históricas y métricas con una sola definición.
 [Límites de los informes de Wialon y analítica en SQL](https://theassettrack.com/es/blog/wialon-reporting-limitations-and-sql-first-analytics/)
- Actualizado 9 de septiembre de 2026 · Estrategia
 ### App de flota marca blanca: hacer o comprar
 Un modelo práctico de hacer o comprar para productos de flota marca blanca: costo a 18 meses, capas de diferenciación y lanzamiento por etapas.
 [App de flota marca blanca: hacer o comprar](https://theassettrack.com/es/blog/white-label-fleet-app-build-vs-buy/)
- Actualizado 11 de septiembre de 2026 · Integración
 ### Integración de Wialon con ERP: arquitectura y errores
 Guía práctica de integración entre Wialon y un ERP: contratos de datos, propiedad de campos, reintentos y conciliación nocturna para un sync estable.
 [Integración de Wialon con ERP: arquitectura y errores](https://theassettrack.com/es/blog/wialon-integration-with-erp-architecture-and-pitfalls/)
