Envío de solicitudes SOAP mediante solicitudes de Python

3 minutos de lectura

avatar de usuario
Deepankar Bajpeyi

¿Es posible usar Python? requests biblioteca para enviar una solicitud SOAP?

  • ¿Cómo es esta solución? stackoverflow.com/q/15569330/2620328

    – sihrc

    11 de agosto de 2013 a las 19:02

  • no se supone que use espuma;

    – Deepankar Bajpeyi

    11 de agosto de 2013 a las 19:04

  • @DeepankarBajpeyi ¿por qué no? Es la única herramienta adecuada para el trabajo.

    –Ian Stapleton Cordasco

    12 de agosto de 2013 a las 3:08

  • Puedes pasar un requests.Session a zeep.

    – perro naranja

    21 de noviembre de 2018 a las 17:29


  • @IanStapletonCordasco, incluso en 2013, la espuma estaba muerta.

    – perro naranja

    21 de noviembre de 2018 a las 17:31

De hecho, es posible.

Aquí hay un ejemplo llamando al servicio Weather SOAP utilizando solicitudes simples lib:

import requests
url="http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL"
#headers = {'content-type': 'application/soap+xml'}
headers = {'content-type': 'text/xml'}
body = """<?xml version="1.0" encoding="UTF-8"?>
         <SOAP-ENV:Envelope xmlns:ns0="http://ws.cdyne.com/WeatherWS/" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
            <SOAP-ENV:Header/>
              <ns1:Body><ns0:GetWeatherInformation/></ns1:Body>
         </SOAP-ENV:Envelope>"""

response = requests.post(url,data=body,headers=headers)
print response.content

Algunas notas:

  • Los encabezados son importantes. La mayoría de las solicitudes SOAP no funcionarán sin los encabezados correctos. application/soap+xml es probablemente el más correcto encabezado a usar (pero el servicio meteorológico prefiere text/xml
  • Esto devolverá la respuesta como una cadena de xml; luego deberá analizar ese xml.
  • Para simplificar, he incluido la solicitud como texto sin formato. Pero la mejor práctica sería almacenar esto como una plantilla, luego puede cargarlo usando jinja2 (por ejemplo), y también pasar variables.

Por ejemplo:

from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('myapp', 'templates'))
template = env.get_template('soaprequests/WeatherSericeRequest.xml')
body = template.render()

Algunas personas han mencionado la biblioteca de espuma. La espuma es probablemente la más correcto manera de interactuar con SOAP, pero a menudo encuentro que entra un poco de pánico cuando tiene WDSL que están mal formados (lo cual, TBH, es más probable que no cuando se trata de una institución que todavía usa SOAP 😉 ).

Puedes hacer lo anterior con espuma así:

from suds.client import Client
url="http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL"
client = Client(url)
print client ## shows the details of this service

result = client.service.GetWeatherInformation() 
print result 

Nota: cuando use espuma, casi siempre terminará necesitando usa al medico!

Finalmente, una pequeña bonificación por depurar SOAP; TCPdump es tu amigo. En Mac, puede ejecutar TCPdump así:

sudo tcpdump -As 0 

Esto puede ser útil para inspeccionar las solicitudes que realmente pasan por el cable.

Los dos fragmentos de código anteriores también están disponibles como resumen:

  • ¿Qué sucede si el servicio solicita nombre de usuario y contraseña? donde anotarlos?

    – Oskars

    9 de diciembre de 2016 a las 11:07

  • @toast38coza wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL –> Error del servidor en la aplicación ‘/WeatherWS’. Actualice el ejemplo.

    – Wlad

    18 de abril de 2017 a las 13:21


  • @toast38coza ¿Dónde obtengo información para encabezados y variables de cuerpo en el ejemplo de solicitudes anterior?

    – Wlad

    18 de abril de 2017 a las 13:29

  • La documentación de Suds ya no está disponible en fedorahosted.org. Aquí está un enlace a una instantánea de la documentación en Wayback Machine.

    – Cristiano largo

    27 de agosto de 2018 a las 22:22

  • Cualquiera que sea el significado de “usar al médico”, ese enlace ahora está muerto.

    – perro naranja

    21 de noviembre de 2018 a las 15:33

Sumando a la última respuesta, asegúrese de agregar a los encabezados los siguientes atributos:

headers={"Authorization": f"bearer {token}", "SOAPAction": "http://..."}

La autorización se entiende cuando necesita algún token para acceder a la API SOAP,

De lo contrario, SOAPAction es la acción que va a realizar con los datos que está enviando,

Entonces, si no necesita autorización, puede sacarla de los encabezados,

Eso funcionó bastante bien para mí,

¿Ha sido útil esta solución?