Kleines Web Service Tutorial mit ZSI für Python

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
Richard_M
User
Beiträge: 11
Registriert: Samstag 13. Januar 2007, 19:22
Wohnort: Nähe Stuttgart
Kontaktdaten:

:D
Hallo zusammen,
ich habe ein kleines Step by Step tutorial geschrieben in dem die nutzung von Web Services durch die ZSI Bibliothek in Python demonstriert wird. Ihr könnt das Tutorial runterladen unter: http://www.mutschler-net.de/18801.html
Über Feedback freue ich mich, viel Spass damit :lol:
Gruß, Richard
Benutzeravatar
Käptn Haddock
User
Beiträge: 169
Registriert: Freitag 24. März 2006, 14:27

Danke :D

Ich denke du wirst bald von mir hören... :D

Gruß Uwe
---------------------------------
have a lot of fun!
Benutzeravatar
Richard_M
User
Beiträge: 11
Registriert: Samstag 13. Januar 2007, 19:22
Wohnort: Nähe Stuttgart
Kontaktdaten:

Hallo, ich habe euch eben noch den Source Code des Projektes unter http://www.mutschler-net.de zum download bereitgestellt.
Gruß, Richard
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Damit dieses Thema auch über die Forensuche gefunden wird. :-)

Stichworte: SOAP, WSDL, Webservice, XML
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
oneDay
User
Beiträge: 1
Registriert: Montag 31. März 2008, 14:18

Hi,
war gerade auf dein Tutorial gestoßen.


Ich habe mit SOAPpy nen Webservice angesprochen und das klappt auch ganz gut.
Allerdings habe ich jetzt noch das Problem, das der Webservice mit username und passwort versehen ist.

Also habe nen Authhandler dazwischen gepackt im SOAP Server (der ist in Java geschrieben) der aus dem MessageContext mit getUsername und getPasswort das überprüft.

Der Client in Python ist halt über
soap = SOAPpy.SOAPProxy(url, namespace)
soap.echo('Hello World')

was auch super klappt solang es ohne http Basic access authentication ist ..
jetzt müssste halt in den http header die infos noch rein ^^ irgendwie

Gruß oneDay
Benutzeravatar
marko
User
Beiträge: 8
Registriert: Mittwoch 2. April 2008, 17:36

hi

lustigerweise bin ich auch grad an dem thema zsi (soappy) und ws-auth.
ich habe es nach doku mit Binding.setAuth() versucht, da schreibt er aber irgendeinen quatsch in den soap-body statt header. also irgendwie will das noch net so.

auch auth_header setzen im client hab ich versucht, da tat sich gar nichts in der nachricht.


nun habe ich nur dies hier rausgefunden:
http://osdir.com/ml/python.pywebsvcs.ge ... 00135.html

you have to monkey-script the serialization like this:

Code: Alles auswählen

def getSOAPHeader:
   typecode = ns0.RequesterCredentials_Dec()
   pyobj = typecode.pyclass()
   pyobj.Credentials = pyobj.new_Credentials ()

   pyobj.Credentials.Username = "myUsername"

   pyobj.Credentials.Password = "bigsecret"

   return pyobj




naja, muss morgen mal noch ein wenig probieren. weiss einer auf die schnelle wie ich in python "monkey-scripte"??? bin noch recht neu in python, deshalb weiss ich noch nicht gleich alle best practices auf anhieb.

habe unter monkey-script verstanden, dass ich zur laufzeit eine bestehende klasse (oder eine funktion daraus) neu zuweise, also ähnlich einer closure. wie ich das in python bewerkstellige weiss ich jedoch noch nicht. vielleicht kann mir ja einer helfen.






EDIT:
hier noch ein paar links zu dem thema:
http://osdir.com/ml/python.pywebsvcs.ge ... 00137.html
http://osdir.com/ml/python.pywebsvcs.ge ... 00023.html
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hallo marko, willkommen im Forum,
marko hat geschrieben:naja, muss morgen mal noch ein wenig probieren. weiss einer auf die schnelle wie ich in python "monkey-scripte"??? bin noch recht neu in python, deshalb weiss ich noch nicht gleich alle best practices auf anhieb.
Monkeypatchen (so heißt das eigentlich) ist eine worst practice und sollte nur dann gemacht werden, wenn man eine Lib hat, wo ein Problem existiert und Upstream kein Interesse hat, es besser zu machen.
marko hat geschrieben:habe unter monkey-script verstanden, dass ich zur laufzeit eine bestehende klasse (oder eine funktion daraus) neu zuweise, also ähnlich einer closure. wie ich das in python bewerkstellige weiss ich jedoch noch nicht. vielleicht kann mir ja einer helfen.
Nicht wie eine Closure sondern wie ein Attribut. In Python sind Funktionen Funktionen höherer Ordnung, daher ist das genauso simpel wie wenn du Attribute einer Klasse überschreibst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
marko
User
Beiträge: 8
Registriert: Mittwoch 2. April 2008, 17:36

hmm...ok.

nur wie wäre dann der beste weg den header-auth shit da rein zu bekommen bevor ich send() aufrufe.

betreffende klasse ist client.py und teil des ZSI-Pakets. ich will ja nict unbedingt den source aus dem paket patchen, sondern lieber ne saubere lösung von aussen um den header-kram da reinzuwuppen.


wie schon gesagt, meine vermutung ist, dass die setAuth()-Methode da was nicht so macht, wie erwartet.

na ich muss morgen mal schauen. danke erstmal für die rückmeldung.



PS: Upstream? Muss man den kennen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

marko hat geschrieben:betreffende klasse ist client.py und teil des ZSI-Pakets. ich will ja nict unbedingt den source aus dem paket patchen, sondern lieber ne saubere lösung von aussen um den header-kram da reinzuwuppen.
Hast du dir doch selbst schon gefunden?
marko hat geschrieben:PS: Upstream? Muss man den kennen?
Upstream ist (Distributions?)Slang für die Autoren einer Software. In deinem Fall ist Upstream die Autoren von ZSI.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
marko
User
Beiträge: 8
Registriert: Mittwoch 2. April 2008, 17:36

ok, also ich hab jetzt mal ein bisschen "geforscht".

also auf ein nachträgliches setzen der auth

Code: Alles auswählen

binding.setAuth(AUTH.httpbasic, "myUsername", "bigsecret")
hat keinerlei auswirkungen. da kommt dann sowas raus:

Code: Alles auswählen

<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Header></SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <setAuth SOAP-ENC:arrayType="xsd:anyType[3]" xsi:type="SOAP-ENC:Array">
      <element id="o965b30" xsi:type="xsd:int">1</element>
      <element id="o1c95820" xsi:type="xsd:string">myUsername</element>
      <element id="o1c95840" xsi:type="xsd:string">bigsecret</element>
    </setAuth>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

ein im constuctor von binding mitgebenes auth (ACHTUNG: nur mit Patch, dazu siehe weiter unten in diesem Beitrag)

Code: Alles auswählen

kw.setdefault("auth", (AUTH.httpbasic, "myUsername", "bigsecret"))
self.binding = client.Binding(url="http://serviceurl", **kw)
dagegen schon. da kommt dann sowas raus:

Code: Alles auswählen

<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Header>
    <ZSI:BasicAuth>
      <ZSI:Name>myUsername</ZSI:Name>
      <ZSI:Password>bigsecret</ZSI:Password>
    </ZSI:BasicAuth>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body xmlns:ns1="http://www.datapower.com/schemas/management">
    <ns1:request></ns1:request>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>



tja, was schliessen wir daraus....nicht immer alles glauben was in der doku steht.




was mir noch aufgefallen ist (zumindest auf meinem system):
im client.py wird der header in Send() folgendermaßen gesetzt

Code: Alles auswählen

# Determine the SOAP auth element.  SOAP:Header element
if self.auth_style & AUTH.zsibasic:
     sw.serialize_header(_AuthHeader(self.auth_user, self.auth_pass), 
           _AuthHeader.typecode)

self.auth_style und AUTH.zsibasic sind 1 und 2. die abfrage

Code: Alles auswählen

if self.auth_style & AUTH.zsibasic
ist trotzdem false. wenn ich das jetzt in

Code: Alles auswählen

if self.auth_style and AUTH.zsibasic
ändere, ist sie (korrekt) true.

Warum ist das so? Ist das Kompiler bedingt oder so?
Zuletzt geändert von marko am Donnerstag 3. April 2008, 14:27, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Das ist deswegen, weil ``&`` und ``and`` zwar beides "und" bedeuten, das eine ist aber ein Binäres Und und das andere ein Logisches. Das kann eine Verwechslung durch den Programmierer sein denn in vielen Sprachen ist das logische Und ``&&``.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
marko
User
Beiträge: 8
Registriert: Mittwoch 2. April 2008, 17:36

Leonidas hat geschrieben:Das ist deswegen, weil ``&`` und ``and`` zwar beides "und" bedeuten, das eine ist aber ein Binäres Und und das andere ein Logisches. Das kann eine Verwechslung durch den Programmierer sein denn in vielen Sprachen ist das logische Und ``&&``.
aaaah, dann wird einiges klarer. scheint vom Upstream tatsächlich so gewollt. Denn irgendwo in der Doku habsch gelesen, dass die nur AUTH.zsibasic zulassen im Moment (was auch immer das heissen soll). Das hat den Wert 2 und ich nehm ja AUTH.httpbasic, das hat den Wert 1. Deshalb eben binär false.
und die dritte möglichkeit AUTH.digest hat 4, also auch false.

Naja, dann muss ich eben AUTH.zsibasic angeben :?


also lautet der funktionierende Code:

Code: Alles auswählen

kw.setdefault("auth", (AUTH.zsibasic, "myUsername", "bigsecret"))
self.binding = client.Binding(url="http://serviceurl", **kw)
Antworten