imagen

Disfrutando de la linea de Comandos I Web Services con Curl

13.Apr.2018 — Julio

Intento no extenderme en cada uno de los puntos.

Linux, potencia en la línea de comandos

Tengo varios programas realizados en python y en Go que recogen datos utilizando web services, los manipulan, y los registran en mi ERP. Luego se utilizan otros servicios también con otros programas para devolver datos actualizados.

Cada vez más me gusta el poder utilizar herramientas que me da el propio sistemas operativo, sin necesidad de realizar programas en python o Go.

Es increíble la potencia de "awk", "sed", "grep" para manipular datos. Es también complicado pero con una línea en "bash" se puede hacer lo que en lenguajes de programación pueden ser 10.


JSON, ¿una moda duradera?

Casi todos los ERP históricamente han trabajado con ficheros de texto plano para compartir datos con otros sistemas. Cada ERP puede tener sus bases de datos distintas pero cuando se intenta automatizar el intercambio de información con otros ERP se utilizan ficheros de texto. No, excels, no. Eso es para el personal "cualificado". Estoy hablando de automatizaciones en los que se busca simpleza, rapidez y economía de recursos.

Ahora casi todos los servicios web devuelven datos en formato JSON. Hace poco era en formato XML. Para mi gusto JSON es demasiado repetitivo en cuanto a la información y ha obligado a que los programadores se creen multitud de librerías, funciones o lo que sea para poder manipular ficheros con ese formato. Muchas veces se pretende sacar unos datos de ese JSON y pasarlos a CSV o TSV para así incorporarlos al ERP de manera más fácil. Reconozco que también por mantener otros sistemas ya creados y que necesitan ese formato de información.

Creo que nos hemos complicado, pero eso sí, cualquiera sin poseer el formato del fichero en cuestión es capaz de leer esos datos si están en formato JSON. Si están en formato csv, y sin cabecera, es mucho más difícil.

¡pero se supone que van a ser tratados por máquinas no por personas! no había la necesidad de complicarse tanto.

Web Services

Maravilloso comando "curl". En una linea obtenemos el resultado de una petición web.

Ahora busca en python o en Go cómo se establece una conexión http. Modificar cabeceras del método http, hacer la petición (GET, POST, PUT ...), recogerla en un objeto, luego en otro... Encontrarás decenas de formas distintas (ya no te digo python2 vs python3), que utilices tal librería, que no, mejor esta otra que la anterior está "deprecated".

Con curl todo en una línea. No tienes que compilar. Tiene un manual extenso, mucho.

Nuestro ejemplo

Hay un web service, que con nuestro usuario y contraseña codificado (no va a ir en plano por la web) y haciendo una petición nos devuelve los pedidos pendientes de cargar.

Problema 1 de las cabeceras HTTP: usuario y contraseña codificado en base64. No problema, también utilizaremos la función del sistema operativo base64.

codigo=echo -n usuario:password | base64

ya está. Ya tenemos nuestra clave codificada.

Y ahora el resto del script en cuanto a las cabeceras (no todas son obligatorias. El cambio del User-Agent es para evitar posibles bloqueos):

```  
host="www.aquiestaelwebservice.net"  
header0="Host:"$host  
header1="Authorization:Basic "$codigo  
header2="Content-type: application/json"  
header3="User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"  
header4="Accept:*/*"  
```

Ahora el link donde hacer la petición. Podemos ponerlo directamente pero yo prefiero a "cachos:"

```  
api="/transfers/api/"  
peticion="pedidos"  
link="https://"$host$api$peticion  
```

Y ahora juntamos todo en el curl guardando además el resultado que nos devuelve en un fichero (opción -o):

```
curl -v -o "transfers.json" -H "${header0}" -H "${header1}" -H "${header2}" -H "${header3}" -H "${header4}" "${link}"  
```

En el fichero transfer.json obtenemos el resultado. Creo que han sido 11 líneas en total pero porque me gusta hacer los scripts paso a paso. Se puede reducir mucho el script final. Tal que así:

```  
codigo=echo -n usuario:password | base64  
header1="Authorization:Basic "$codigo  
curl -o "transfers.json" -H "Host:www.aquiestaelwebservice.net" -H "${header1}" "https:www.aquiestaelwebservice.net/transfer/api/pedidos"  
```

Lo sé. Se podría meter todo en una, pero de verdad, prefiero un poco de claridad.

Editado 26.04.2018:

Se puede evitar todo lo referente a la autenticación Básica de HTTP, en este caso la obtención del header1 si en la llamada al curl añadimos --user "usuario:password" --basic Con eso el script nos queda en una sola línea.

Siguiente post, ¿cómo tratar ese JSON también en bash?

Tags: bash, json, jq, curl

Comments? Tweet