¿Cómo puedo consumir un servicio web WSDL (SOAP) en Python?

Quiero usar un servicio web basado en SOAP WSDL en Python. He visto el código Dive Into Python , pero el módulo SOAPpy no funciona en Python 2.5.

He intentado usar suds, que funciona parcialmente, pero se rompe con ciertos tipos (suds.TypeNotFound: tipo no encontrado: ‘elemento’).

También he mirado al Cliente pero esto no parece ser compatible con WSDL.

Y he mirado a ZSI pero parece muy complejo. ¿Alguien tiene algún código de ejemplo para ello?

El WSDL es https://ws.pingdom.com/soap/PingdomAPI.wsdl y funciona bien con el cliente PHP 5 SOAP.

Te recomendaría que eches un vistazo a SUDS.

“Suds es un cliente ligero de Python SOAP para consumir servicios web”.

Recientemente me topé con el mismo problema. Aquí está la sinopsis de mi solución:

Bloques de código constituyentes básicos necesarios

Los siguientes son los bloques de código básicos requeridos de su aplicación cliente.

  1. Sección de solicitud de sesión: solicitar una sesión con el proveedor.
  2. Sección de autenticación de sesión: proporcionar credenciales al proveedor
  3. Sección cliente: crear el cliente
  4. Sección del encabezado de seguridad: agregue el encabezado WS-Security al cliente
  5. Sección de consumo: consumir las operaciones (o métodos) disponibles según sea necesario

¿Qué módulos necesitas?

Muchos sugirieron utilizar módulos de Python como urllib2; sin embargo, ninguno de los módulos funciona, al menos para este proyecto en particular.

Entonces, aquí está la lista de los módulos que necesita obtener. En primer lugar, necesita descargar e instalar la última versión de la espuma desde el siguiente enlace:

pypi.python.org/pypi/suds-jurko/0.4.1.jurko.2

Además, necesita descargar e instalar las solicitudes y los módulos suds_requests de los siguientes enlaces respectivamente (descargo de responsabilidad: soy nuevo en publicar aquí, por lo que no puedo publicar más de un enlace por ahora).

pypi.python.org/pypi/requests

pypi.python.org/pypi/suds_requests/0.1

Una vez que haya descargado e instalado estos módulos con éxito, estará listo.

El código

Siguiendo los pasos descritos anteriormente, el código se parece a lo siguiente: Importaciones:

import logging from suds.client import Client from suds.wsse import * from datetime import timedelta,date,datetime,tzinfo import requests from requests.auth import HTTPBasicAuth import suds_requests 

Solicitud de sesión y autenticación:

 username=input('Username:') password=input('password:') session = requests.session() session.auth=(username, password) 

Crea el cliente:

 client = Client(WSDL_URL, faults=False, cachingpolicy=1, location=WSDL_URL, transport=suds_requests.RequestsTransport(session)) 

Añadir WS-Security Header:

 ... addSecurityHeader(client,username,password) .... def addSecurityHeader(client,username,password): security=Security() userNameToken=UsernameToken(username,password) timeStampToken=Timestamp(validity=600) security.tokens.append(userNameToken) security.tokens.append(timeStampToken) client.set_options(wsse=security) 

Tenga en cuenta que este método crea el encabezado de seguridad que se muestra en la Fig.1. Por lo tanto, su implementación puede variar según el formato de encabezado de seguridad correcto proporcionado por el propietario del servicio que está consumiendo.

Consume el método (o operación) relevante:

 result=client.service.methodName(Inputs) 

Registro :

Una de las mejores prácticas en implementaciones como esta es el registro para ver cómo se ejecuta la comunicación. En caso de que haya algún problema, facilita la depuración. El siguiente código hace el registro básico. Sin embargo, puede registrar muchos aspectos de la comunicación además de los que se muestran en el código.

 logging.basicConfig(level=logging.INFO) logging.getLogger('suds.client').setLevel(logging.DEBUG) logging.getLogger('suds.transport').setLevel(logging.DEBUG) 

Resultado:

Aquí está el resultado en mi caso. Tenga en cuenta que el servidor devolvió HTTP 200. Este es el código de éxito estándar para la solicitud-respuesta HTTP.

 (200, (collectionNodeLmp){ timestamp = 2014-12-03 00:00:00-05:00 nodeLmp[] = (nodeLmp){ pnodeId = 35010357 name = "YADKIN" mccValue = -0.19 mlcValue = -0.13 price = 36.46 type = "500 KV" timestamp = 2014-12-03 01:00:00-05:00 errorCodeId = 0 }, (nodeLmp){ pnodeId = 33138769 name = "ZION 1" mccValue = -0.18 mlcValue = -1.86 price = 34.75 type = "Aggregate" timestamp = 2014-12-03 01:00:00-05:00 errorCodeId = 0 }, }) 

Hay una biblioteca relativamente nueva que es muy prometedora y aunque todavía está mal documentada, parece muy limpia y pythonic: python zeep .

Vea también esta respuesta para un ejemplo.

En este momento (a partir de 2008), todas las bibliotecas de SOAP disponibles para Python apestan. Recomiendo evitar el soap si es posible. La última vez que nos vimos obligados a usar un servicio web SOAP de Python, escribimos una envoltura en C # que manejaba el SOAP en un lado y hablaba COM por el otro.

Busco periódicamente una respuesta satisfactoria a esto, pero hasta ahora no he tenido suerte. Yo uso soapUI + solicitudes + trabajo manual.

Renuncié y utilicé Java la última vez que tuve que hacer esto, y simplemente abandoné algunas veces la última vez que quise hacer esto, pero no fue esencial.

Después de haber utilizado con éxito la biblioteca de solicitudes el año pasado con la API RESTful de Project Place, se me ocurrió que tal vez podría simplemente realizar manualmente las solicitudes de SOAP que quiero enviar de una manera similar.

Resulta que no es demasiado difícil, pero requiere mucho tiempo y es propenso a errores, especialmente si los campos tienen nombres inconsistentes (en el que estoy trabajando actualmente tiene ‘Id. De trabajo’, Id. De trabajo ‘y’ Id. De trabajo ‘. Utilizo soapUI para cargar el WSDL para facilitar la extracción de puntos finales, etc. y realizar algunas pruebas manuales. Hasta ahora he tenido la suerte de no haber sido afectado por los cambios en cualquier WSDL que esté usando.

Zeep es una biblioteca SOAP decente para Python que coincide con lo que estás pidiendo: http://docs.python-zeep.org

No es cierto. SOAPpy no funciona con Python 2.5, funciona, aunque es muy simple y realmente muy básico. Si quieres hablar con un servicio web más complicado, ZSI es tu único amigo.

La demostración realmente útil que encontré está en http://www.ebi.ac.uk/Tools/webservices/tutorials/python : esto realmente me ayudó a entender cómo funciona ZSI.

Si está haciendo rodar la suya, le recomiendo encarecidamente visitar http://effbot.org/zone/element-soap.htm .

SOAPpy ahora está obsoleto, AFAIK, reemplazado por ZSL. Es un punto discutible, porque no puedo lograr que ninguno de los dos funcione, mucho menos comstackr, en Python 2.5 o Python 2.6

 #!/usr/bin/python # -*- coding: utf-8 -*- # consume_wsdl_soap_ws_pss.py import logging.config from pysimplesoap.client import SoapClient logging.config.dictConfig({ 'version': 1, 'formatters': { 'verbose': { 'format': '%(name)s: %(message)s' } }, 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'verbose', }, }, 'loggers': { 'pysimplesoap.helpers': { 'level': 'DEBUG', 'propagate': True, 'handlers': ['console'], }, } }) WSDL_URL = 'http://www.webservicex.net/stockquote.asmx?WSDL' client = SoapClient(wsdl=WSDL_URL, ns="web", trace=True) client['AuthHeaderElement'] = {'username': 'someone', 'password': 'nottelling'} #Discover operations list_of_services = [service for service in client.services] print(list_of_services) #Discover params method = client.services['StockQuote'] response = client.GetQuote(symbol='GOOG') print('GetQuote: {}'.format(response['GetQuoteResult']))