web-dev-qa-db-fra.com

Comment utiliser un service Web WSDL (SOAP) en Python?

Je souhaite utiliser un service Web WSDL SOAP en Python. J'ai examiné le code Plonger dans Python mais le module SOAPpy ne fonctionne pas sous Python 2.5.

J'ai essayé d'utiliser sud qui fonctionne en partie, mais rompt avec certains types (suds.TypeNotFound: type non trouvé: 'item').

J'ai également examiné Client mais cela ne semble pas prendre en charge WSDL.

Et j'ai regardé ZSI mais ça a l'air 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 correctement avec le PHP 5 SOAP = client.

119
DavidM

Je recommanderais que vous jetiez un coup d'oeil à (~ ~ ~ ~] mousses [~ # ~]

"Suds est un client léger SOAP python pour utiliser des services Web."

49
Yusufk

Il existe une bibliothèque relativement nouvelle qui est très prometteuse et encore mal documentée mais qui semble très propre et Pythonic: python zeep .

Voir aussi cette réponse pour un exemple.

19
lorenzog

Je suis récemment tombé sur le même problème. Voici le synopsis de ma solution:

blocs de code constitutifs de base nécessaires

Vous trouverez ci-dessous les blocs de code de base requis pour votre application client.

  1. Section de demande de session: demande une session avec le fournisseur
  2. Section d'authentification de session: fournissez les informations d'identification au fournisseur
  3. Section client: créer le client
  4. Section En-tête de sécurité: ajoutez l'en-tête WS-Security au client.
  5. Section Consommation: consomme les opérations (ou méthodes) disponibles en fonction des besoins

De quels modules avez-vous besoin?

Beaucoup ont suggéré d'utiliser Python des modules tels que urllib2; cependant, aucun des modules ne fonctionne, du moins pour ce projet particulier.

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 suds à partir du lien suivant:

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

De plus, vous devez télécharger et installer les modules de demandes et de modules sudsrequests à partir des liens suivants (avertissement: je suis nouveau dans la publication ici, je ne peux donc pas publier plus d'un lien pour le moment).

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, vous êtes prêt à partir.

Le code

En suivant les étapes décrites précédemment, le code se présente comme suit: Imports:

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 authentification:

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

Créez le client:

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

Ajouter un en-tête WS-Security:

...
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é illustré à la Fig.1. Votre implémentation peut donc varier en fonction du format correct de l'en-tête de sécurité fourni par le propriétaire du service que vous utilisez.

Consommez la méthode (ou opération) appropriée:

result=client.service.methodName(Inputs)

journalisation:

L'une des meilleures pratiques dans des implémentations telles que celle-ci est la journalisation pour voir comment la communication est exécutée. En cas de problème, le débogage est facile. 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 renvoyé HTTP 200. Il s'agit du code de réussite 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
      },
 })
19
Teddy Belay

En ce moment (à partir de 2008), toutes les SOAP bibliothèques disponibles pour Python suck. Je recommande d'éviter si SOAP 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 gérait le SOAP d’un côté et qui parlait COM sur l'autre.

9
Matthew Scouten

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

5
Hanni Ali

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 j'ai nécessaire pour le faire, et j'ai tout simplement abandonné à quelques reprises la dernière fois que j'ai voul faire cela, mais ce n'était pas essentiel.

Après avoir utilisé avec succès la bibliothèque de requêtes l’année dernière avec l’API RESTful de Project Place, je me suis dit que je pourrais peut-être simplement lancer manuellement les demandes SOAP que je veux envoyer de la même manière.

Il s'avère que ce n'est pas trop difficile, mais cela est prend beaucoup de temps et est sujet à des erreurs, en particulier si les champs sont nommés de manière incohérente (celui sur lequel je travaille actuellement a 'jobId', JobId 'et' JobID 'J'utilise soapUI pour charger le fichier WSDL afin de faciliter l'extraction des points de terminaison, etc., et d'effectuer des tests manuels. Jusqu'à présent, j'ai eu la chance de ne pas avoir été affecté par les modifications apportées au fichier WSDL que j'utilise.

5
Hywel Thomas

Ce n'est pas vrai. SOAPpy ne fonctionne pas avec Python 2.5 - cela fonctionne, même si c'est 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 se trouve sur http://www.ebi.ac.uk/Tools/webservices/tutorials/python - cela m'a vraiment aidé à comprendre le fonctionnement de ZSI.

2
zgoda

SOAPpy est maintenant obsolète, autant que je sache, remplacé par ZSL. C’est un point discutable, car je ne parviens pas à faire fonctionner l’un ou l’autre, et encore moins la compilation, que ce soit sur Python 2.5 ou Python 2.6

1
user122299
#!/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
Down the Stream

Si vous lancez le vôtre, je vous recommande vivement de regarder http://effbot.org/zone/element-soap.htm .

1
sj26