Comment puis-je consommer un service web WSDL (SOAP) en Python?

je veux utiliser un service web basé sur WSDL SOAP en Python. J'ai regardé le plonger dans le code de Python, mais le module SOAPpy ne fonctionne pas sous Python 2.5.

j'ai essayé d'utiliser suds qui fonctionne en partie, mais casse avec certains types (suds.TypeNotFound: Type non trouvé: 'item').

j'ai aussi regardé Client mais cela ne semble pas supporter WSDL.

et j'ai regardé ZSI mais il semble très complexe. Quelqu'un at-il un exemple de code pour cela?

le WSDL est https://ws.pingdom.com/soap/PingdomAPI.wsdl et fonctionne très bien avec le client SOAP PHP 5.

115
demandé sur Shadow Wizard 2008-09-22 18:58:53

11 réponses

je sais que c'est un vieux fil, mais il apparaissait au sommet des résultats de Google donc je voulais partager une discussion plus actuelle sur Python et SOAP.

voir: http://www.diveintopython.net/soap_web_services/index.html

43
répondu Tony 2014-08-08 21:24:02

je vous recommande d'avoir un oeil à SUDS

" Suds est un client SOAP Python léger pour consommer des Services Web."

49
répondu Yusufk 2010-05-13 19:02:39

j'ai récemment trébuché sur le même problème. Voici le résumé de ma solution:

blocs de code constituant de base nécessaires

ce qui suit sont les blocs de code de base requis de votre application client

  1. section de demande de Session: demande de session avec le fournisseur
  2. section d'authentification de Session: fournir des justificatifs d'identité au fournisseur
  3. section Client: créer le Client
  4. Sécurité section d'en-Tête: ajouter le WS-Security-Tête du Client
  5. section consommation: consommer les opérations (ou les méthodes) disponibles au besoin

de quels modules avez-vous besoin?

beaucoup ont suggéré D'utiliser des modules Python tels que urllib2 ; cependant, aucun des modules ne fonctionne-au moins pour ce particulier projet.

Donc, voici la liste des modules que vous devez obtenir. Tout d'abord, vous devez télécharger et installer la dernière version de la mousse à partir du lien suivant:

pypi.python.org/pypi/suds-jurko/0.4.1.jurko.2

en outre, vous devez télécharger et installer les modules requests et suds_requests à partir des liens suivants respectivement (disclaimer: je suis nouveau à poster ici, donc je ne peux pas poster plus qu'un lien pour l'instant).

pypi.python.org/pypi/requests

pypi.python.org/pypi/suds_requests/0.1

une fois que vous avez téléchargé et installé ces modules avec succès, vous pouvez y aller.

le code

suivant les étapes décrites plus haut, le code ressemble à ce qui suit:: Importations:

import logging
from suds.client import Client
from suds.wsse import *
from datetime import timedelta,date,datetime,tzinfo
import requests
from requests.auth import HTTPBasicAuth
import suds_requests

demande de Session et l'authentification:

username=input('Username:')
password=input('password:')
session = requests.session()
session.auth=(username, password)

créer le Client:

client = Client(WSDL_URL, faults=False, cachingpolicy=1, location=WSDL_URL, transport=suds_requests.RequestsTransport(session))

ajouter WS-Security Header:

...
addSecurityHeader(client,username,password)
....

def addSecurityHeader(client,username,password):
    security=Security()
    userNameToken=UsernameToken(username,password)
    timeStampToken=Timestamp(validity=600)
    security.tokens.append(userNameToken)
    security.tokens.append(timeStampToken)
    client.set_options(wsse=security)

veuillez noter que cette méthode crée l'en-tête de sécurité représenté à la figure 1.1. Ainsi, votre implémentation peut varier en fonction du format d'en-tête de sécurité correct fourni par le propriétaire du service que vous consommez.

consomment la méthode pertinente (ou fonctionnement):

result=client.service.methodName(Inputs)

Journalisation :

l'une des meilleures pratiques dans de telles implémentations est la journalisation pour voir comment la communication est exécutée. En cas de problème, cela facilite le débogage. Le code suivant fait la journalisation de base. Cependant, vous pouvez enregistrer de nombreux aspects de la communication en plus de ceux décrits dans le code.

logging.basicConfig(level=logging.INFO) 
logging.getLogger('suds.client').setLevel(logging.DEBUG) 
logging.getLogger('suds.transport').setLevel(logging.DEBUG)

résultat:

Voici le résultat dans mon cas. Notez que le serveur a retourné HTTP 200. C'est le code de succès standard pour la requête-réponse HTTP.

(200, (collectionNodeLmp){
   timestamp = 2014-12-03 00:00:00-05:00
   nodeLmp[] = 
      (nodeLmp){
         pnodeId = 35010357
         name = "YADKIN"
         mccValue = -0.19
         mlcValue = -0.13
         price = 36.46
         type = "500 KV"
         timestamp = 2014-12-03 01:00:00-05:00
         errorCodeId = 0
      },
      (nodeLmp){
         pnodeId = 33138769
         name = "ZION 1"
         mccValue = -0.18
         mlcValue = -1.86
         price = 34.75
         type = "Aggregate"
         timestamp = 2014-12-03 01:00:00-05:00
         errorCodeId = 0
      },
 })
18
répondu Teddy Belay 2017-02-17 20:02:28

il y a une bibliothèque relativement nouvelle qui est très prometteuse et encore mal documentée, qui semble très propre et pythonique: Python zeep .

Voir aussi cette réponse pour un exemple.

13
répondu lorenzog 2017-05-23 12:02:41

en ce moment (à partir de 2008), toutes les bibliothèques SOAP disponibles pour Python suck. Je recommande d'éviter le savon si possible. La dernière fois que nous avons été forcés d'utiliser un service Web SOAP de Python, nous avons écrit un wrapper en C# qui manipulait le SOAP d'un côté et parlait COM out de l'autre.

7
répondu Matthew Scouten 2014-08-08 21:24:30

je cherche périodiquement une réponse satisfaisante à cela, mais pas de chance jusqu'à présent. J'utilise soapUI + demandes + travail manuel.

j'ai abandonné et utilisé Java la dernière fois que je ai eu besoin de pour faire ceci, et j'ai simplement abandonné quelques fois la dernière fois que je voulais pour faire ceci, mais ce n'était pas essentiel.

ayant utilisé avec succès la bibliothèque de requêtes l'an dernier avec L'API RESTful de Project Place, il m'est venu à l'esprit que peut-être je pourrais juste faire rouler les demandes de savon que je veux envoyer d'une manière similaire.

S'avère que ce n'est pas trop difficile, mais est longue et sujette à l'erreur, surtout si les champs sont nommés de façon incohérente (celui sur lequel je travaille actuellement a 'jobId', JobId' et 'JobID'. J'utilise soapUI pour charger le WSDL pour le rendre plus facile à extraire les points terminaux etc et effectuer quelques tests manuels. Jusqu'à présent, j'ai été chanceux de ne pas avoir été touché par des modifications à n'importe quel WSDL que j'utilise.

5
répondu Hywel Thomas 2013-11-07 11:54:38

Zeep est une bibliothèque de savon décente pour Python qui correspond à ce que vous demandez: http://docs.python-zeep.org

3
répondu Hanni Ali 2017-04-23 21:24:43

ce n'est pas vrai SOAPpy ne fonctionne pas avec Python 2.5 - cela fonctionne, bien que ce soit très simple et vraiment, vraiment basique. Si vous voulez parler à un service Web plus compliqué, ZSI est votre seul ami.

la démo vraiment utile que j'ai trouvée est à http://www.ebi.ac.uk/Tools/webservices/tutorials/python - cela m'a vraiment aidé à comprendre comment fonctionne ZSI.

2
répondu zgoda 2008-09-22 19:38:22

si vous roulez la vôtre, je vous recommande vivement de regarder http://effbot.org/zone/element-soap.htm .

1
répondu sj26 2010-01-19 11:13:16

SOAPpy est désormais obsolète, AFAIK, remplacé par ZSL. C'est un point discutable, parce que je ne peux pas faire fonctionner l'un ou l'autre, encore moins compiler, sur Python 2.5 ou Python 2.6

1
répondu the Tin Man 2014-08-08 21:33:48
#!/usr/bin/python
# -*- coding: utf-8 -*-
# consume_wsdl_soap_ws_pss.py
import logging.config
from pysimplesoap.client import SoapClient

logging.config.dictConfig({
    'version': 1,
    'formatters': {
        'verbose': {
            'format': '%(name)s: %(message)s'
        }
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'pysimplesoap.helpers': {
            'level': 'DEBUG',
            'propagate': True,
            'handlers': ['console'],
        },
    }
})

WSDL_URL = 'http://www.webservicex.net/stockquote.asmx?WSDL'
client = SoapClient(wsdl=WSDL_URL, ns="web", trace=True)
client['AuthHeaderElement'] = {'username': 'someone', 'password': 'nottelling'}

#Discover operations
list_of_services = [service for service in client.services]
print(list_of_services)

#Discover params
method = client.services['StockQuote']

response = client.GetQuote(symbol='GOOG')
print('GetQuote: {}'.format(response['GetQuoteResult']))
1
répondu Down the Stream 2017-03-23 16:06:36