it-swarm.com.de

Wie kann ich einen WSDL-Webdienst (SOAP) in Python verwenden?

Ich möchte einen auf WSDL SOAP basierenden Webdienst in Python verwenden. Ich habe mir den Code Dive Into Python angesehen, aber das SOAPpy-Modul funktioniert nicht unter Python 2.5.

Ich habe versucht, suds zu verwenden, was teilweise funktioniert, aber mit bestimmten Typen bricht (suds.TypeNotFound: Typ nicht gefunden: 'item').

Ich habe mir auch Client angesehen, aber dies scheint WSDL nicht zu unterstützen.

Und ich habe mir ZSI angesehen, aber es sieht sehr komplex aus. Hat jemand einen Beispielcode dafür?

Die WSDL lautet https://ws.pingdom.com/soap/PingdomAPI.wsdl und funktioniert problemlos mit dem PHP 5 SOAP -Client.

119
DavidM

Ich würde empfehlen, dass Sie einen Blick auf SUDS werfen

"Suds ist ein kompakter SOAP python Client für den Konsum von Web Services."

49
Yusufk

Es gibt eine relativ neue Bibliothek, die sehr vielversprechend und wenn auch noch schlecht dokumentiert ist, sehr sauber und pythonisch erscheint: Python Zeep .

Siehe auch diese Antwort für ein Beispiel.

19
lorenzog

Ich bin kürzlich auf dasselbe Problem gestoßen. Hier ist die Zusammenfassung meiner Lösung:

Grundlegende Codebausteine ​​erforderlich

Im Folgenden finden Sie die erforderlichen Basiscodeblöcke Ihrer Clientanwendung

  1. Abschnitt Sitzungsanfrage: Fordern Sie eine Sitzung beim Anbieter an
  2. Abschnitt zur Sitzungsauthentifizierung: Geben Sie dem Anbieter Anmeldeinformationen
  3. Kundenbereich: Erstellen Sie den Kunden
  4. Abschnitt "Sicherheitskopf": Fügen Sie den WS-Sicherheitskopf zum Client hinzu
  5. Verbrauchsabschnitt: Verbrauchen Sie die verfügbaren Operationen (oder Methoden) nach Bedarf

Welche Module benötigen Sie?

Viele schlugen vor, Python Module wie urllib2 zu verwenden; jedoch funktioniert keines der Module - zumindest nicht für dieses spezielle Projekt.

Hier ist die Liste der Module, die Sie benötigen. Zunächst müssen Sie die neueste Version von suds über den folgenden Link herunterladen und installieren:

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

Außerdem müssen Sie Requests- und suds_requests-Module über die folgenden Links herunterladen und installieren (Haftungsausschluss: Ich kann hier nur einen Link posten, daher kann ich momentan nur einen Link posten).

pypi.python.org/pypi/requests

pypi.python.org/pypi/suds_requests/0.1

Sobald Sie diese Module erfolgreich heruntergeladen und installiert haben, können Sie loslegen.

Der Code

In Anlehnung an die zuvor beschriebenen Schritte sieht der Code folgendermaßen aus: 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

Sitzungsanfrage und Authentifizierung:

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

Erstellen Sie den Client:

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

WS-Security Header hinzufügen:

...
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)

Bitte beachten Sie, dass mit dieser Methode der in Abb. 1 dargestellte Sicherheitskopf erstellt wird. Aus diesem Grund kann Ihre Implementierung variieren, abhängig vom korrekten Sicherheits-Header-Format, das vom Eigentümer des von Ihnen genutzten Dienstes bereitgestellt wird.

Verbrauchen Sie die entsprechende Methode (oder Operation):

result=client.service.methodName(Inputs)

Protokollierung:

Eine der Best Practices bei solchen Implementierungen wie dieser ist das Protokollieren, um zu sehen, wie die Kommunikation ausgeführt wird. Falls es ein Problem gibt, erleichtert dies das Debuggen. Der folgende Code führt die grundlegende Protokollierung durch. Sie können jedoch viele Aspekte der Kommunikation zusätzlich zu den im Code dargestellten protokollieren.

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

Ergebnis:

Hier ist das Ergebnis in meinem Fall. Beachten Sie, dass der Server HTTP 200 zurückgegeben hat. Dies ist der Standarderfolgscode für die HTTP-Anforderungsantwort.

(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

Im Moment (ab 2008) sind alle SOAP Bibliotheken verfügbar für Python saugen. Ich empfehle, SOAP nach Möglichkeit zu vermeiden Als wir das letzte Mal gezwungen wurden, einen SOAP Webdienst von Python zu verwenden, haben wir einen Wrapper in C # geschrieben, der SOAP auf einer Seite handhabte und COM sprach aus dem anderen.

9
Matthew Scouten

Zeep ist eine anständige SOAP Bibliothek für Python), die genau Ihren Wünschen entspricht: http://docs.python-zeep.org

5
Hanni Ali

Ich suche regelmäßig nach einer zufriedenstellenden Antwort, aber bisher kein Glück. Ich benutze soapUI + Anfragen + Handarbeit.

Ich gab auf und benutzte Java das letzte Mal, als ich gebraucht dies tat, und gab einfach das letzte Mal ein paar Mal auf, als ich wollte um dies zu tun, aber es war nicht wesentlich.

Nachdem ich die Anforderungsbibliothek im letzten Jahr erfolgreich mit der RESTful-API von Project Place verwendet hatte, kam mir der Gedanke, dass ich die SOAP) -Anforderungen, die ich auf ähnliche Weise senden möchte, möglicherweise von Hand rollen könnte.

Es stellt sich heraus, dass dies nicht allzu schwierig ist, aber es ist zeitaufwendig und fehleranfällig, insbesondere wenn Felder uneinheitlich benannt sind (die Felder, an denen ich zurzeit arbeite, haben 'jobId', JobId 'und' JobID ') Ich verwende soapUI, um die WSDL zu laden, um das Extrahieren von Endpunkten usw. zu vereinfachen und einige manuelle Tests durchzuführen. Bisher hatte ich das Glück, nicht von Änderungen an einer von mir verwendeten WSDL betroffen zu sein.

5
Hywel Thomas

Es ist nicht wahr, SOAPpy funktioniert nicht mit Python 2.5 - es funktioniert, obwohl es sehr einfach und sehr, sehr einfach ist. Wenn Sie mit einem komplizierteren Webservice sprechen möchten, ist ZSI Ihr einziger Freund.

Die wirklich nützliche Demo, die ich gefunden habe, ist unter http://www.ebi.ac.uk/Tools/webservices/tutorials/python - das hat mir wirklich geholfen zu verstehen, wie ZSI funktioniert.

2
zgoda

SOAPpy ist mittlerweile veraltet, AFAIK, ersetzt durch ZSL. Es ist ein strittiger Punkt, weil ich weder auf Python 2.5 noch auf Python 2.6) einen zum Laufen bringen kann, geschweige denn kompilieren kann

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

Wenn Sie Ihre eigenen rollen, würde ich empfehlen, sich http://effbot.org/zone/element-soap.htm .

1
sj26