Servicios Web en Python – Parte 1

Fundamentos

Un “Web Service” o “Servicio Web”, en términos simples, es como su nombre lo indica, un servicio al que se puede acceder a través de la Web.

Detallando un poco, un servicio Web es una funcionalidad que implementa un dispositivo para exponer a través de la red, la respuesta a solicitud de información, usando el protocolo HTTP. Es una forma de pedir información a través de la red a un servidor remoto.

¿No es lo mismo que navegar por la Web? Podría decirse que sí. Pero un navegador accede a una dirección Web (es todo lo que sabe), y en esa dirección hay cualquier tipo de contenido que por lo general es enorme.

Un servicio Web accede a una dirección web, pero no para cargar una página, sino para solicitar una respuesta específica. Puede ser para pedir la hora del sistema, información sobre tráfico, clima, etc.

Al igual que las páginas Web, los Servicios Web, permiten intercambiar información independientemente de la plataforma en la que operen las partes cliente y servidor.

Los servicios Web, trabajan intercambiando información en formato de texto y especialmente con XML, usando estándares abiertos. El uso de texto y XML permite una implementación y verificación sencilla, pero incrementa el tamaño de los paquetes de datos.

Una trama sencilla de HHTP para la solicitud a un Servicio Web podría ser:

<?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:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
> 
<SOAP-ENV:Body>
<saludo SOAP-ENC:root="1">
</saludo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Arquitectura

A diferencia de las conexiones Web tradicionales donde se habla de un Cliente y Servidor, en la tecnología de Web Service, se suele hablar más de Consumidor o Solicitante (Cliente) y Proveedor (Servidor), si bien, es común encontrar las típicas denominaciones de Cliente-Sevidor también en Web Service.

Adicionalmente se puede añadir un tercer elemento al que podríamos llamar el Registro del Servicio, como se indica en el siguiente diagrama:

El proveedor «Proveedor» expone a la red, ciertas funciones que permitirán a los clientes obtener la información requerida.  El cliente es quien accede a estas funciones expuestas. El registro es quien contiene información sobre los servicios expuestos, en el servidor.

Protocolos

Existen diversos protocolos para la implementación de Web Services.

  • RPC.- Técnica de llamada a procedimientos que se ejecutan remotamente. Permite ejecutar ciertas funciones solicitadas por un cliente, en un servidor, usando la Red.
  • XML-RPC.- Es un protocolo sencillo para manejo de llamadas a procedimientos remotos. Está basado en XML.
  • SOAP.- Es uno de los protocolos más usados. Está basado en XML. Es bastante completo y flexible. Nace como una versión avanzada de XML-RPC.
  • REST. Más que un protocolo, es una arquitectura que define reglas para la creación de Servicios Web.
  • WS-Security. Protocolo que agrega un nivel de seguridad para las comunicaciones con Web Service.

La mayoría de proveedores de Web Service, exponen sus servicios, usando el formato WDSL. Un WDSL es un texto en XML, que indica las funciones que el servidor expone al público.

Implementaciones

Existen diversas implementaciones para implementar Web Service en Python sobre SOAP. Estas son solo algunas:

*SOAPProxy. Requiere instalar otras liberías. Existe ejemplos detallados en el libro “Dive Into Python”.

*PySimpleSOAP. Librería ligera para SOAP, tanto para el lado del cliente como del servidor.

*Suds. Funciona bien con SOAP, es sencillo pero SOLO permite hacer clientes (consumidores) de Web Service.

*Zeep. Trabaja en Python 2 y 3. Funciona bien con SOAP, solo permite hacer clientes (consumidores) de Web Service.

 

Librería XML-RPC

Es una librería estándar de Python, así que no es necesario descargarla. Esta librería solo permite Web Service en el protocolo XML-RPC. Puede manejar clientes o servidores:

Ejemplo de servidor sencillo, que espera solicitudes por el puerto 8080:

from SimpleXMLRPCServer import SimpleXMLRPCServer

def holamundo(nombre):
    return "hola   :" + str(nombre)

server = SimpleXMLRPCServer(("localhost", 8080))
print("Escuchando por el puerto 8080...")
server.register_function(holamundo)
server.serve_forever()

Y el cliente:

import xmlrpclib
s = xmlrpclib.ServerProxy('http://localhost:8080')
print s.holamundo('Perico de los palotes')

Este ejemplo, funcionará con el cliente y el servidor en el mismo equipo. Para hacer visible al servidor, desde la red, se debe especificar la dirección IP completa en SimpleXMLRPCServer() en el código del servidor:

server = SimpleXMLRPCServer(("192.168.1.31", 8080))

Un ejemplo más completo de https://docs.python.org/2/library/simplexmlrpcserver.html, muestra cómo se implementa servidor y cliente:

Lado del servidor:

from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler

# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)

# Create server
server = SimpleXMLRPCServer(("localhost", 8000),
requestHandler=RequestHandler)
server.register_introspection_functions()

# Register pow() function; this will use the value of
# pow.__name__ as the name, which is just 'pow'.
server.register_function(pow)

# Register a function under a different name
def adder_function(x,y):
return x + y
server.register_function(adder_function, 'add')

# Register an instance; all the methods of the instance are
# published as XML-RPC methods (in this case, just 'div').
class MyFuncs:
def div(self, x, y):
return x // y

server.register_instance(MyFuncs())

# Run the server's main loop
server.serve_forever()

Lado del cliente :

import xmlrpclib

s = xmlrpclib.ServerProxy('http://localhost:8000')
print s.pow(2,3) # Returns 2**3 = 8
print s.add(2,3) # Returns 5
print s.div(5,2) # Returns 5//2 = 2

# Print list of available methods
print s.system.listMethods()

Hay que saber que en XML-RPC, es común completar la URL, con la cadena “/RPC2”, como una indicación de que se está requiriendo una llamada a un Web Service XML-RPC. Esto es una convención que suele usar Python y diversas librerías de otros lenguajes.

Librerías SUDS

Trabaja con SOAP, pero solo como cliente. Es ligero y práctico. Pero si se desea implementar un proveedor de Web Service, puede convenir usar otra librería.

La versión clásica de SUDS solo trabaja con Python2. Para Python 2 existe SUDS-py3.

SUDS se encuentra publicado en https://github.com/suds-community/suds.

Prueba de cliente en Suds:

from suds.client import Client
url = 'http://www.webservicex.net/globalweather.asmx?WSDL'
client = Client(url)
print client

Este cliente debería mostrar:

Suds ( https://fedorahosted.org/suds/ )  version: 0.3.9 GA  build: R659-20100219
 
Service ( GlobalWeather ) tns="http://www.webserviceX.NET"
   Prefixes (0)
   Ports (2):
      (GlobalWeatherSoap)
         Methods (2):
            GetCitiesByCountry(xs:string CountryName, )
            GetWeather(xs:string CityName, xs:string CountryName, )
         Types (0):
      (GlobalWeatherSoap12)
         Methods (2):
            GetCitiesByCountry(xs:string CountryName, )
            GetWeather(xs:string CityName, xs:string CountryName, )
         Types (0):


Sé el primero en comentar

Dejar una contestacion

Tu dirección de correo electrónico no será publicada.


*