Web Services examples using "raw" xml?

J

John Gordon

I'm developing a program that will use web services, which I have never
used before.

There are several tutorials out there that advise you to get the WSDL
and then call a method (such as wsdl2py) that inspects the wsdl and
automagically generates the python classes and methods you need for
interacting with that web service.

I've tried this, and have run into a number of roadblocks that have left
me frustrated.

For example I tried wsdl2py() from the ZSI package, and got this error:

Error loading services.xml:
namespace of schema and import match

I tried WSDL.Proxy() from the SOAPpy package and eventually end up
with this error:

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 6

I tried Client() from the suds package, and got this error:

File "/usr/lib/python2.3/site-packages/suds/client.py", line 59
@classmethod
^
SyntaxError: invalid syntax

I'm not an expert; I have no idea what any of these errors mean, and I
have no idea how to go about resolving them.

So I decided to take a step back and see if I could bypass all the fancy
automagic methods and just create my own SOAP xml message from scratch
and then send it to the web server. That would work, surely.

But I'm having a tough time finding some good examples of that, because
all the tutorials I've found just tell you to use the aforementioned
magic methods, which unfortunately don;t seem to be working for me.

Does anyone have some good examples of code that builds a "raw" xml SOAP
message and sends it to a webserver, then reads the response? I think
that would be a good place for me to start.

Thanks for any replies.
 
J

John Nagle

John said:
I'm developing a program that will use web services, which I have never
used before.

Web services in general, or some Microsoft interface?

John Nagle
 
D

Diez B. Roggisch

John said:
I'm developing a program that will use web services, which I have never
used before.

There are several tutorials out there that advise you to get the WSDL
and then call a method (such as wsdl2py) that inspects the wsdl and
automagically generates the python classes and methods you need for
interacting with that web service.

I've tried this, and have run into a number of roadblocks that have left
me frustrated.

Welcome to the wonderful world of SOAP. If you didn't know - the S
stands for simple [1].

I don't want to go into a rant about the why and how SOAP sucks, and why
it's support in Python is lacking - to say the least.

What we did in a similar situation was this:

- got hold of a client that was able to speak with the server. In your
case, a .NET-client shouldn't be hard to get working.
- monitor the traffic that went on between the client and server using
some HTTP-proxy or WireShark.
- mimicked the server-side protocol by dynamising the sniffed traffic
through an XML-templating tool, genshi in our case.

Sounds archaic, and complicated? Yes. Blame SOAP (and Microsoft, it's
biggest proponent)


Diez


[1] http://72.249.21.88/nonintersecting/2006/11/15/the-s-stands-for-simple/
 
A

Asun Friere

  File "/usr/lib/python2.3/site-packages/suds/client.py", line 59
    @classmethod
    ^
SyntaxError: invalid syntax

If memory serves me correctly, decorators were introduced in
python2.4. That would account for your SyntaxError.
 
S

Stefan Behnel

John said:
I'm developing a program that will use web services, which I have never
used before.

There are several tutorials out there that advise you to get the WSDL
and then call a method (such as wsdl2py) that inspects the wsdl and
automagically generates the python classes and methods you need for
interacting with that web service.

There are a number of tools that help in building WS clients. One is
soaplib. It's pretty easy to use and was recently ported (V0.8) to the lxml
XML library. I actually still use a 0.7.x, also fixed to work with Py2.3.

It doesn't do any code generation. Instead, you have to write up a short
code snippet that describes the WS interface. Works pretty well.

I tried WSDL.Proxy() from the SOAPpy package and eventually end up
with this error:

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 6

Is that while parsing the WSDL file? Have you tried pushing it through an
XML parser yourself (or opening it with an XML editor) to see if it really
is XML?

Or does this happen while communicating with the remote side? (in which
case I'd trap the wire and look at the transferred XML messages)

I tried Client() from the suds package, and got this error:

File "/usr/lib/python2.3/site-packages/suds/client.py", line 59
@classmethod
^
SyntaxError: invalid syntax

That's a Py2.4-ism. You can make the code backwards compatible by replacing all

@classmethod
def some_function():
...

lines with

def some_function():
...

some_function = classmethod(some_function)

That's how I fixed up soaplib, BTW.

So I decided to take a step back and see if I could bypass all the fancy
automagic methods and just create my own SOAP xml message from scratch
and then send it to the web server. That would work, surely.

Yes, that's a good way also. And it avoids an additional dependency on a
convoluted SOAP library.

But I'm having a tough time finding some good examples of that, because
all the tutorials I've found just tell you to use the aforementioned
magic methods, which unfortunately don;t seem to be working for me.

http://effbot.org/zone/element-soap.htm

Stefan
 
J

John Gordon

Is that while parsing the WSDL file? Have you tried pushing it through an
XML parser yourself (or opening it with an XML editor) to see if it really
is XML?

The 'invalid token' error happens if the argument to WSDL.Proxy() is a
string containing a URL beginning with https. (It doesn't happen with a
http URL, but I'm stuck with https.)

As a next step, I grabbed the content from the https url in a browser,
saved it to a file, inserted it into the python code as a large string,
and passed that string to WSDL.Proxy().

That produced a KeyError 'targetNamespace' from this snippet of XML:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://schemas.microsoft.com/exchange/services/2006/messages" schemaLocation="messages.xsd"/>
</xs:schema>

I looked at the code and it apparently requires that the parent tag of
<xs:import> have a targetNamespace attribute. So I made one up and added
it, like so:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="xyz">

I have no idea if this was the right thing to do, but it did let me advance
to the next error:

Traceback (most recent call last):
File "soappytest.py", line 1020, in ?
server = jrgWSDL.Proxy(wsdlFile)
File "/home/gordonj/wsdl/jrgSOAPpy/jrgWSDL.py", line 75, in __init__
service = self.wsdl.services[0]
File "/home/gordonj/wsdl/jrgwstools/Utility.py", line 631, in __getitem__
return self.list[key]
IndexError: list index out of range

After poking around in the code a bit more, I think that self.wsdl.services
is supposed to be a collection of all the services offered by the wsdl, but
it's actually empty, which is why it throws an error when it tries to
access the first element.

So that's where I'm stuck at the moment. I have no idea why
self.wsdl.services isn't getting populated correctly -- or even if that's
the real problem!

Any suggestions?
 
P

Piet van Oostrum

DBR> Welcome to the wonderful world of SOAP. If you didn't know - the S stands
DBR> for simple [1].

Stood. Like the O was supposed to stand for Object. Now out of shame
they tend to talk more about `Service Oriented Architecture Protocol'.
Whichever is a greater abomination you may choose (that almost sounds
like Yoda-speak).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top