93 votes

Envoi d'une demande SOAP à l'aide de Python Requests

Est-il possible d'utiliser l'outil Python requests bibliothèque pour envoyer une requête SOAP ?

180voto

toast38coza Points 73

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ère text/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 :

0voto

Jesus Perez Points 1

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,

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X