12.4. Depuración de servicios web SOAP

Las bibliotecas de SOAP proporcionan una manera sencilla de comprobar lo que está sucediendo tras la escena.

Activar la depuración es simplemente cuestión de cambiar dos indicadores en la configuraciónl SOAPProxy.

Ejemplo 12.7. Depuración de servicios web SOAP

>>> from SOAPpy import SOAPProxy
>>> url = 'http://services.xmethods.net:80/soap/servlet/rpcrouter'
>>> n = 'urn:xmethods-Temperature'
>>> server = SOAPProxy(url, namespace=n)     1
>>> server.config.dumpSOAPOut = 1            2
>>> server.config.dumpSOAPIn = 1
>>> temperature = server.getTemp('27502')    3
*** Outgoing SOAP ******************************************************
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getTemp xmlns:ns1="urn:xmethods-Temperature" SOAP-ENC:root="1">
<v1 xsi:type="xsd:string">27502</v1>
</ns1:getTemp>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
************************************************************************
*** Incoming SOAP ******************************************************
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<ns1:getTempResponse xmlns:ns1="urn:xmethods-Temperature"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:float">80.0</return>
</ns1:getTempResponse>

</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
************************************************************************

>>> temperature
80.0
1 Primero creamos SOAPProxy igual que siempre, con la URL y el espacio de nombres del servicio.
2 Segundo, activamos la depuración cambiando server.config.dumpSOAPIn y server.config.dumpSOAPOut.
3 Tercero, invoque el método remoto SOAP de la manera normal. La biblioteca de SOAP imprimirá tanto el documento XML de la petición saliente como el de la respuesta entrante. Éste es todo el trabajo duro que está haciendo SOAPProxy por nosotros. Intimidante, ¿verdad? Analicémoslo.

La mayoría del documento de petición XML que se envía al servidor es una plantilla. Ignore todas las declaraciones de espacio de nombres; van a ser lo mismo (o parecido) en todas las invocaciones SOAP. El centro de la “llamada a función” es este fragmento dentro del elemento <Body>:

<ns1:getTemp                                 1
  xmlns:ns1="urn:xmethods-Temperature"       2
  SOAP-ENC:root="1">
<v1 xsi:type="xsd:string">27502</v1>         3
</ns1:getTemp>
1 El nombre del elemento es a su vez el nombre de la función, getTemp. SOAPProxy utiliza getattr para despachar. En lugar de llamar a varios métodos locales diferentes basándose en el nombre del método, utiliza este último para construir el documento XML de petición.
2 El elemento XML de la función está contenido en un espacio de nombres específico, que es el que especificamos cuando creamos el objeto SOAPProxy. No se preocupe por el SOAP-ENC:root; también sale de una plantilla.
3 Los argumentos de la función se traducen también a XML. SOAPProxy hace uso de introspección sobre cada argumento para determinar el tipo de datos (en este caso una cadena). El tipo del argumento va en el atributo xsi:type, seguido por una cadena con el valor en sí.

El documento XML devuelto es igualmente sencillo de entender, una vez que sabe lo que ha de ignorar. Concéntrese en este fragmento dentro del <Body>:

<ns1:getTempResponse                             1
  xmlns:ns1="urn:xmethods-Temperature"           2
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:float">80.0</return>       3
</ns1:getTempResponse>
1 El servidor encapsula el valor de vuelta de la función dentro de un elemento <getTempResponse>. Por convención, este elemento encapsulador es el nombre de la función, más Response. Pero en realidad podría ser casi cualquier cosa; la cosa importante en que se fija SOAPProxy no es el nombre del elemento, sino el espacio de nombres.
2 El servidor devuelve la respuesta en el mismo espacio de nombres que usamos en la consulta, el mismo que especificamos cuando creamos el SOAPProxy. Más adelante en este capítulo veremos lo que sucede si olvidamos especificar el espacio de nombres al crear el SOAPProxy.
3 Se especifica el valor devuelto junto con su tipo de datos (coma flotante). SOAPProxy utiliza este tipo de dato explícito para crear un objeto de Python del tipo nativo correcto y lo devuelve.