Est-il possible d'utiliser l'outil Python requests
bibliothèque pour envoyer une requête SOAP ?
Réponses
Trop de publicités?C'est en effet possible.
Voici un exemple d'appel du service SOAP Météo à l'aide de la librairie de requêtes simples :
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
Quelques notes :
- Les en-têtes sont importants. La plupart des demandes SOAP ne fonctionneront pas sans les bons en-têtes.
application/soap+xml
est probablement le plus correct à utiliser (mais le weatherservice préfèretext/xml
- Cela renverra la réponse sous la forme d'une chaîne de caractères xml - vous devrez alors analyser ce xml.
- Par souci de simplicité, j'ai inclus la demande en texte brut. Mais la meilleure pratique serait de stocker ceci comme un modèle, alors vous pouvez le charger en utilisant jinja2 (par exemple) - et aussi passer dans les variables.
Par exemple :
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('myapp', 'templates'))
template = env.get_template('soaprequests/WeatherSericeRequest.xml')
body = template.render()
Certaines personnes ont mentionné la bibliothèque des mousses. Suds est probablement le plus correct d'interagir avec SOAP, mais je trouve souvent qu'il panique un peu lorsque vous avez des WDSL qui sont mal formées (ce qui, TBH, est plus probable que non lorsque vous avez affaire à une institution qui utilise encore SOAP ;) ).
Vous pouvez faire ce qui précède avec de la mousse comme ceci :
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: lorsque vous utilisez de la mousse, vous finirez presque toujours par avoir besoin de utiliser le médecin !
Enfin, un petit bonus pour déboguer SOAP ; TCPdump est votre ami. Sur Mac, vous pouvez exécuter TCPdump comme suit :
sudo tcpdump -As 0
Cela peut être utile pour inspecter les demandes qui passent effectivement par le câble.
Les deux extraits de code ci-dessus sont également disponibles sous forme de gists :
En complément de la dernière réponse, veillez à ajouter aux en-têtes les attributs suivants :
headers={"Authorization": f"bearer {token}", "SOAPAction": "http://..."}
L'autorisation est nécessaire lorsque vous avez besoin d'un jeton pour accéder à l'API SOAP,
Sinon, le SOAPAction est l'action que vous allez effectuer avec les données que vous envoyez,
Donc, si vous n'avez pas besoin de l'autorisation, vous pouvez la retirer des en-têtes,
Ça a bien marché pour moi,