SOAP-Optionen in Python
(Auszug aus "Python & XML" von Christopher A. Jones & Fred L. Drake, Jr.)
Die Unterstützung für Webdienste in Python ist noch im Entstehen begriffen und nicht vollständig. Zum gegenwärtigen Zeitpunkt gibt es eine lebhafte Debatte in der XML-SIG (Python XML Special Interest Groups), was SOAP-Client- und -Server-Implementierungen und ihre Interaktionsmöglichkeiten angeht.
SOAP und WSDL, und damit Webdienste, werden zum großen Teil von Firmen wie IBM und Microsoft vorangetrieben. Microsoft bietet eine robuste Client- und Server-Unterstützung für Webdienste in seinem SOAP-Toolkit, während IBM wesentlich zum Apache-SOAP-Projekt beiträgt. Beide Lager bieten Unterstützung für zwei häufige Zu-gangsarten zu Webdiensten: einen Zugang über RPC-artige Proxies und einen über die SOAP-Serialisierung.
Sie können heutzutage Python-Clients für Webdienste einfach implementieren, indem Sie einen der Python-Brückenmechanismen zu Subsystemen wie COM und Java benutzen. Die Unterstützung von COM in Python ist exzellent und wird dadurch verfügbar, daß das Paket PythonCOM installiert wird (Teil des Pakets win32all.exe von der ActiveState-Website). Eine detaillierte Anleitung wird im Abschnitt »Anforderungen bei der Verwendung von MSSOAP« gegeben.
Mit den heute verbreiteten APIs für Webdienste sind Sie sehr wahrscheinlich in der Lage, Ihren Python-Code schnell so zu modifizieren, daß er echte Python-Unterstützung von Webdiensten verwendet, sobald diese ausgereift ist, obwohl es vielleicht wünschenswerter wäre, die Logik selbst in Python zu schreiben, aber APIs aus Python heraus zu benutzen, die in schnellerem C++ implementiert sind. Python ist wegen seines robusten Objektmodells, den ausgefeilten Text- und Dateibearbeitungen sowie dem Zugriff auf Komponenten eine großartige »Klebesprache«. Komponenten zu benutzen, die ressourcenintensiv sind (etwa Parser oder SOAP-Clients), mag vielleicht besser funktionieren, wenn die Komponenten in schnellem nativen Code geschrieben sind und von Ihrem Python-Code gesteuert werden.
Mit einer plattformübergreifenden Ausnahme verlassen sich die Python-Client-Beispiele dieses Abschnitts hauptsächlich auf COM, um eine Brücke zu Microsofts ausgereiftem SOAP-Serialisierer und SOAP-Connector zu schlagen. Daher laufen die Python-Beispiele in diesem Abschnitt wegen der Verwendung von COM vorwiegend auf Windows-Plattformen. Die SOAPy-API wird jedoch ebenfalls abgedeckt. Dies ist eine echte RPC-artige SOAP-Client-Implementierung in Python. SOAPy sollte überall dort laufen, wo Python läuft.
Arbeiten mit SOAPy
Im Moment unterstützt SOAPy RPC-artige Interaktionen mit Webdiensten, die über WSDL veröffentlicht werden. SOAPy ist zur Zeit auf SourceForge verfügbar. SOAPy ist inhärent plattformübergreifend, weil es eine native Python-Implementierung ist.
Mit SOAPy zu arbeiten ist sehr einfach, da es so entworfen wurde, daß ein entfernter Webdienst so transparent dargestellt wird, als ob er ein lokales Python-Objekt wäre. Wenn Sie eine der Quellcode-Distributionen von SOAPy herunterladen, finden Sie darin einige Beispiele, in denen SOAPy seine Fähigkeiten zeigt. Im get_temperature-Beispiel etwa, das in SOAPy enthalten ist, können Sie eine Postleitzahl eingeben und einen entfernten Wetterdienst nach der aktuellen Temperatur fragen. Auf diese Weise erfragt man also die Temperatur in Woodinville, Washington:
C:\c9>python get_temperature.py 98072
Temperature for 98072 = 53.0 degrees F
Auch wenn diese Anwendung beeindruckt, schürt sie sofort die Neugier zu erfahren, wie SOAPy funktioniert. SOAPy führt diesen Trick in drei Zeilen Code aus:
import soap
server = soap.get_proxy('http://www.xmethods.net/sd/TemperatureService.wsdl')
temperature = server.getTemp(zipcode=zip)
Das Geheimnis besteht darin, daß SOAPy die WSDL-Datei interpretiert und ein lokales Stellvertreter-Objekt für Sie erzeugt, das anscheinend über alle Methoden des entfernten Dienstes verfügt.
Beim Arbeiten mit SOAPy ist get_proxy idealerweise die einzige Methode, die Sie aufrufen. Danach sollten Sie in der Lage sein, die Methoden zu benutzen, die in der WSDL-Datei beschrieben sind, die ihrerseits beim entfernten Dienst vorliegt.
Arbeiten mit MSSOAP
Wenn Sie mit MSSOAP arbeiten, haben Sie die Wahl zwischen einem RPC-Client oder einem Serialisierungs-Client.
Der RPC-Client funktioniert prinzipiell genauso wie SOAPy, allerdings gibt es einige subtile Unterschiede. Um z. B. eine Verbindung mit einer entfernten Dienstbeschreibung zu initialisieren, verwenden Sie die Methode mssoapinit statt get_proxy in SOAPy, aber der Effekt ist am Ende der gleiche, wie hier gezeigt wird:
import win32com.client
sc = win32com.client.Dispatch("MSSOAP.SoapClient")
sc.mssoapinit("http://WebServiceDomain/service.wsdl")
response = sc.methodName(param, param)
print(response)
Noch einmal: Der Effekt von RPC-Implementierungen von Webdiensten ist der, es Ihnen zu ermöglichen, mit einem entfernten Objekt so zu arbeiten, als ob es lokal vorliegen würde. Die Serialisierungsmethode funktioniert ein wenig anders, gibt Ihnen jedoch eine feinere Kontrolle darüber, wie eine SOAP-Anfrage strukturiert ist, und macht es Ihnen möglich, mit einem Dienst zu arbeiten, ohne sich notwendigerweise auf eine WSDL-Dienstbeschreibungsdatei zu verlassen.
Serialisierungsgrundlagen von MSSOAP
Die Serialisierung zu benutzen macht mehr Arbeit als RPC, hat aber eigene Vor- und Nachteile. Bei der Serialisierung können Sie sehr fein steuern, wie eine SOAP-XML-Anfrage genau erscheint. Wenn Sie Serialisierung implementieren, können Sie mit einem Webdienst interagieren, ohne daß Sie WSDL verstehen müssen, was mit zunehmender Reife der SOAP-Implementierungen (Client und Server) von beachtlichem Wert sein könnte.
Der Hauptunterschied zwischen RPC und Serialisierung ist die WSDL-Datei. Diese Datei stellt einer RPC-Implementierung die Informationen zur Verfügung, die sie über die Endpunkte des Dienstes braucht, wie z. B. die beteiligten URIs und Namensräume oder die Parameter und deren Typen. Ohne RPC und WSDL müßten Sie diese zusätzlichen Details von Hand angeben.
Hinzufügen von URIs und Namensräumen
Um ein SOAP-Paket mit MSSOAP zu erzeugen, werden ein paar Objekte benötigt, aber beginnen sollten Sie mit dem connector und dem serializer. Sie müssen den connector mit Informationen versorgen, die normalerweise in der WSDL-Datei enthalten sind. Sie müssen z. B. den Endpunkt, den SOAP-Action-URI und den Namensraum angeben:
import win32com.client
SoapActionUri = "http://tempuri.org/action/Calc.Add"
ElementNamespace = "http://tempuri.org/message/"
EndPointUrl = \"http://centauri/MSSoapSamples/Calc/Service/SrSz/AspVbs/Calc.asp"
connector = win32com.client.Dispatch("MSSOAP.HttpConnector")
connector.SetProperty("EndPointURL", EndPointUrl)
connector.SetProperty("SoapAction", SoapActionUri)
connector.BeginMessage( )
Der connector ist nun darauf vorbereitet, sich mit dem Dienst zu verbinden. Sie müssen jetzt nur noch den SOAP-Umschlag vorbereiten und den Aufruf durchführen. Der SOAP-Umschlag wird ebenfalls manuell vorbereitet.
serializer = win32com.client.Dispatch("MSSOAP.SoapSerializer")
serializer.Init(connector.InputStream)
Nachdem der serializer erzeugt wurde, wird er an den connector zum Schreiben an den Dienst angefügt.
Erzeugen des SOAP-Umschlags
Benutzen Sie die Methoden von serializer, um das SOAP-Paket tatsächlich zu bauen und die Parameter anzugeben, inklusive der Zielmethode. Die folgenden Zeilen bereiten ein SOAP-Paket zum Versand an einen Rechendienst vor, der für eine Methode namens Add die ganzzahligen Parameter A und B erwartet:
# Erzeuge SOAP-Umschlag
serializer.startEnvelope( )
serializer.startBody( )
serializer.startElement("Add", ElementNamespace, '', "m")
serializer.startElement("A")
serializer.writeString("4")
serializer.endElement( )
serializer.startElement("B")
serializer.writeString("5")
serializer.endElement( )
serializer.endElement( )
serializer.endBody( )
serializer.endEnvelope( )
# Beende SOAP-Nachricht
connector.EndMessage( )
Wie im obigen Code gezeigt, wird dem connector anschließend mit einem Aufruf von EndMessage mitgeteilt, daß die komplette SOAP-Nachricht vorbereitet wurde.
Durchführung des Aufrufs
Nachdem Sie mit der Konstruktion von serializer und connector fertig sind, besteht der letzte Schritt darin, ein reader-Objekt zu instanziieren, um den Dienst auf Fehler zu prüfen und das Ergebnis des Aufrufs zu erhalten.
reader = win32com.client.Dispatch("MSSOAP.SoapReader")
reader.Load(connector.OutputStream)
Hier wird der reader mit dem Ausgabestrom des connectors assoziiert, um das Ergebnis des Aufrufs des Dienstes zu erhalten. Das Fault-Attribut des readers gibt Erfolg oder Mißerfolg an.
if reader.Fault:
print("Fehler: ", reader.faultstring.Text)
print reader.RPCResult.Text
Die Antwort des Dienstes ist im Objekt reader.RPCResult enthalten. In diesem speziellen Fall lautet die Antwort des Rechendienstes »9« und entspricht der Summe der angegebenen Parameter 4 und 5.
<< zurück | vor >> |
Tipp der data2type-Redaktion: Zum Thema Python & XML bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an: |
Copyright © 2002 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Python & XML" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.
O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de