Отправка запроса SOAP с использованием запросов Python

Возможно ли использовать библиотеку Python requests для отправки запроса SOAP?

Ответ 1

Это действительно возможно.

Вот пример вызова службы SOAP погоды с использованием простых запросов 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

Некоторые примечания:

  • Заголовки важны. Большинство запросов SOAP не будут работать без правильных заголовков. application/soap+xml, вероятно, более правильный заголовок для использования (но служба погоды предпочитает text/xml
  • Это вернет ответ как строку xml - тогда вам нужно будет проанализировать этот xml.
  • Для простоты я включил запрос как обычный текст. Но лучше всего хранить это как шаблон, тогда вы можете загрузить его с помощью jinja2 (например), а также передать переменные.

Например:

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

Некоторые люди упомянули библиотеку пены. Suds, вероятно, является более правильным способом взаимодействия с SOAP, но я часто обнаруживаю, что он немного паникует, когда у вас есть WDSL, которые плохо сформированы (что, TBH, более вероятно, чем когда вы имеете дело с учреждением, которое все еще использует SOAP;)).

Вы можете сделать это с помощью пены:

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 

Примечание: при использовании пены, вы почти всегда будете нуждаться в использовании врача!

Наконец, небольшой бонус для отладки SOAP; TCPdump - ваш друг. На Mac вы можете запустить TCPdump следующим образом:

sudo tcpdump -As 0 

Это может быть полезно для проверки запросов, которые действительно проходят через провод.

Вышеупомянутые два фрагмента кода также доступны в виде gists: