Отправка SOAP-запроса с использованием Python-запросов
Можно ли использовать Python requests
библиотека для отправки SOAP-запроса?
2 ответа
Это действительно возможно.
Вот пример вызова службы Weather 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
вероятно, более правильный заголовок для использования (но Weatherservice предпочитает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. Suds, вероятно, является более правильным способом взаимодействия с SOAP, но я часто нахожу, что он немного паникует, когда у вас плохо сформированы WDSL (что, TBH, более вероятно, чем нет, когда вы имеете дело с учреждением, которое все еще использует SOAP;)).
Вы можете сделать вышеперечисленное с помощью suds следующим образом:
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
Это может быть полезно для проверки запросов, которые фактически передаются по проводам.
Вышеупомянутые два фрагмента кода также доступны в виде гистограмм:
Добавляя к последнему ответу, убедитесь, что вы добавили в заголовки следующие атрибуты:
headers={"Authorization": f"bearer {token}", "SOAPAction": "http://..."}
Авторизация предназначена, когда вам нужен токен для доступа к SOAP API,
В противном случае SOAPAction — это действие, которое вы собираетесь выполнить с данными, которые вы отправляете,
Так что, если вам не нужна авторизация, вы можете вытащить это из заголовков,
Это сработало очень хорошо для меня,