|
SoapServer
SOAP ServerSoapDispatcher is intended to be used from web frameworks (see Web2Py) to expose webservice functionalities. Although, a minimal HTTP server is included to test basic features or show how to embed it other applications if no web framework is available. For testing, SOAPHandler (a minimal BaseHTTPRequestHandler implementation) can be used. Following is some sample code. WARNING: current release (experimental) of this server is in alpha status, not intended to be used in production by now. ExampleThis example expose an adder function that receive two integers and returns his sum. Basic instrospection information about the webservice can be seen using a browser:
For a nicer webpage with complete method help and esy interface, see Web2Py implementation. ServerPython's built-in HTTPServer can be used with SOAPHandler to expose a minimal SOAP Server: from pysimplesoap.server import SoapDispatcher, SOAPHandler
from BaseHTTPServer import HTTPServer
def adder(a,b):
"Add two values"
return a+b
dispatcher = SoapDispatcher(
'my_dispatcher',
location = "http://localhost:8008/",
action = 'http://localhost:8008/', # SOAPAction
namespace = "http://example.com/sample.wsdl", prefix="ns0",
trace = True,
ns = True)
# register the user function
dispatcher.register_function('Adder', adder,
returns={'AddResult': int},
args={'a': int,'b': int})
print "Starting server..."
httpd = HTTPServer(("", 8008), SOAPHandler)
httpd.dispatcher = dispatcher
httpd.serve_forever()ClientTo test this minimal server, a minimal client can be used: from pysimplesoap.client import SoapClient, SoapFault
# create a simple consumer
client = SoapClient(
location = "http://localhost:8008/",
action = 'http://localhost:8008/', # SOAPAction
namespace = "http://example.com/sample.wsdl",
soap_ns='soap',
trace = True,
ns = False)
# call the remote method
response = client.Adder(a=1, b=2)
# extract and convert the returned value
result = response.AddResult
print int(result)The expected output should be: --------------------------------------------------------------------------------
POST http://localhost:8008/
SOAPAction: "http://localhost:8008/Adder"
Content-length: 329
Content-type: text/xml; charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<Adder xmlns="http://example.com/sample.wsdl">
<a>1</a><b>2</b></Adder>
</soap:Body>
</soap:Envelope>
date: Tue, 20 Jul 2010 23:39:21 GMT
status: 200
content-type: text/xml
server: BaseHTTP/0.3 Python/2.5.4
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body><AdderResponse xmlns="http://example.com/sample.wsdl"><AddResult>3</AddResult></AdderResponse></soap:Body>
</soap:Envelope>
================================================================================
3
|
Hi,
I am new to soap with Python; your work sounds very interesting:
easy to use good compatibility with other clients compact code :-)
Small typo in this example: the name arg is missing for the dispatcher. One question: I looked at the example in the source code (server.py); you use a list of dicts here. Is there another way to deal with arrays?
Thanks for your comment,
Sorry but I cannot find the typo, can you fill an Issue?
About arrays, yes, they are converted to lists. If you need something special, you can use raw SimpleXMLElement objects. BTW, if you want, we can discuss this at the Python Soap List: http://mail.python.org/mailman/listinfo/soap
Hello, I would like to know what return types can be retrieved to the client (in this case i can see that you use int and str).
Thanks, Martin
Martin: supported types are: {str:'string',unicode:'string', bool:'boolean', short:'short', byte:'byte', int:'int', long:'long', integer:'integer', float:'float', double:'double', Decimal:'decimal', datetime.datetime:'dateTime', datetime.date:'date'}, and using lists and dicts you can return more complex objects.
Some types are aliases for python ones, you can look at the code for more details: http://code.google.com/p/pysimplesoap/source/browse/simplexml.py#54
Can you please provide an example to stop the server too? I am doing following but port(8008) is never released.
class configurationServer(threading.Thread): def __init__(self): self.server = None self.dispatcher = None self.config = None threading.Thread.__init__(self) def run(self): self.dispatcher = SoapDispatcher( 'my_dispatcher', location = "http://localhost:8008/", action = 'http://localhost:8008/', # SOAPAction namespace = "http://example.com/sample.wsdl", trace = True, ns = True) self.server = HTTPServer(("",8008),SOAPHandler) self.server.dispatcher = self.dispatcher self.server.serve_forever() def stop(self): self.server.shutdown() self.server.server_close()My main class is calling start() and stop() on this thread.
gill.teena: Can you please fill an issue?
I don't fully understand you problem, but I think you have a multi-threading issue here, serve_forever() should block and create new threads out of your control, you should have to look at: http://docs.python.org/library/basehttpserver.html#more-examples for a server that doesn't run forever.
Please I using python 3 and not work the library SOAP, please help!
Hi, have you done anything about WS-Security functions? Regards
I always receive the following error when I try to call the function mentioned above (response = client.Adder(a=1, b=2)):
Traceback (most recent call last): File "SOAPClient.py", line 10, in <module> ns = True) File "/Users/Nico/Development/Python/PackagePrototype/test/client.py", line 103, in __init__ self.http = Http(timeout=TIMEOUT, cacert=cacert, proxy=proxy, sessions=sessions) File "/Users/Nico/Development/Python/PackagePrototype/test/transport.py", line 88, in __init__ raise RuntimeError('timeout is not supported with urllib2 transport') RuntimeError: timeout is not supported with urllib2 transportI have a 1:1 copy of the client and server code above. Starting the server first and calling the registered function. The server seems to start OK, with no errors.
Please help, thanks!
Oke, fixed it. I had to change the variable timeout from 60 to None in the module client. Now it works fine!