Hi, all:
Recently, I have been do something about python webservice. Above all the methods of python webservice, soaplib is welcome and popular. When using soaplib, some problems puzzled me as follows.
porlbem 1: soaplib provide client-side or not? Usually, I use soaplib as follows:
# file-name: soaplib_server.py: # -*- coding:utf-8 -*-
from soaplib.wsgi_soap import SimpleWSGISoapApp from soaplib.service import soapmethod from soaplib.serializers.clazz import ClassSerializer from soaplib.serializers.primitive import String, Integer, Array, DateTime
class SMS(ClassSerializer): class types: mobile = String content = String
class SMSService(SimpleWSGISoapApp): @soapmethod(String, _returns=Array(SMS)) def get_sms(self,id): sms_lst = [] sms = SMS() sms.mobile = "13011292217" sms.content = "hi, it's a test!" sms_lst.append(sms) return sms_lst
def make_client(): from soaplib.client import make_service_client client = make_service_client('http://localhost:7789/' ,SMSService()) return client
if __name__=='__main__': try: from wsgiref.simple_server import make_server server = make_server('localhost', 7789,SMSService()) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
#file-name: suds_client.py import suds
def test_soaplib3(): import logging logging.basicConfig(level=logging.ERROR)
url = "http://localhost:7789/?wsdl" client = suds.client.Client(url,cache=None) print 'client', client output = client.service.get_sms('jia') print 'output', output
#NOTE: Certainly, it's okay. Below is the output:
#output: client Suds ( https://fedorahosted.org/suds/ ) version: 0.3.7 GA build: R580-20091016
Service ( SMSService ) tns="SMSService.SMSService" Prefixes (1) ns0 = "SMSService.SMSService" Ports (1): (SMSService) Methods (1): get_sms(xs:string id, ) Types (4): SMS SMSArray get_sms get_smsResponse
output (SMSArray){ _type = "tns:SMSArray" SMS[] = (SMS){ content = "hi, it's a test!" mobile = "13011292217" }, }
#NOTE: do you find the "def make_client():" in the server-side ? It's no use when we use suds_client.py. Now, let me talk the problem: I think soaplib is only a server-side and without client, you also can find the words as follows in "http://soaplib.github.com/soaplib/2_0/": "Soaplib is an easy to use Python library for publishing SOAP web services using WSDL 1.1 standard, and answering SOAP 1.1 requests. With a very small amount of code, soaplib allows you to write a useful web service and deploy it as a WSGI application. (Non-WSGI scenarios are also supported.)" Most of scenes, soaplib make as server and suds did for client. They can work together well. In a web page, I found someone use client by soaplib, the client can be write as follows:
# file-name: soaplib_client.py # -*- coding:utf-8 -*-
from soaplib_server3 import SMSService from soaplib_server3 import make_client import lxml.etree as et
a = make_client() ret = a.get_sms('jia') print 'ret:', ret print 'type of ret:', type(ret) for i,r in enumerate(ret): print 'i:',i, r.mobile, r.content
#output: ret: [<soaplib_server3.SMS object at 0x8ecf7ec>] type of ret: <type 'list'> i: 0 13011292217 hi, it's a test!
#NOTE: now, the questions are : 1: Whether soaplib can provide client? 2: If the answer for question 1 is okay, then the second question is : how to provide a webservice client using soaplib? Is the method "client = make_service_client('http://localhost:7789/' ,SMSService())" which is be used in my soaplib_serve.py? 3: if you agree that soaplib can make as websevice client-side, I would like to ask: The client relays so heavily on sever-side, in the client-side, it requests some classes or modules in server side are imported. If we use soaplib-client to invoke a remote server(it may be developed in Java, C#, php or other language, or python which is not in the some local), how we get the class in server?
I do not whether i speak my question clearly. In actual fact, what I eager to know is how to provide a client-side using soaplib if soaplib can.
part 2: Is there someone find it spend much time and not stable to invoke soaplib using suds as follows. #NOTE: the code can also be found in " http://soaplib.github.com/soaplib/2_0/pages/helloworld.html" # soaplib_server.py import soaplib from soaplib.core.service import soap from soaplib.core.service import rpc, DefinitionBase from soaplib.core.model.primitive import String, Integer from soaplib.core.server import wsgi from soaplib.core.model.clazz import Array from soaplib.core import Application class HelloWorldService(DefinitionBase):
@soap(String,Integer,_returns=Array(String)) def say_hello(self,name,times): results = [] for i in range(0,times): results.append('Hello, %s'%name) return results
if __name__=='__main__': print 'server begin running...' try: from wsgiref.simple_server import make_server soap_application = Application([HelloWorldService], 'tns')
wsgi_application = wsgi.Application(soap_application) server = make_server('localhost', 7789, wsgi_application) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
# suds.py import suds def test_soaplib():
url = "http://localhost:7789/?wsdl" client = suds.client.Client(url,cache=None) print 'client', client output = client.service.say_hello('jia',3) print 'output', output
when you invoke sus.py , it takes much time and a long time later returns the right result ”output (stringArray){ string[] = "Hello, jia", "Hello, jia", "Hello, jia", } “ or the exception below(it‘s not present exceptions as follows. most of time it return the result successfully after 2 or 3 minutes).
Traceback (most recent call last): File "suds_client.py", line 774, in <module> test_soaplib() File "suds_client.py", line 627, in test_soaplib client = suds.client.Client(url,cache=None) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/client.py", line 109, in __init__ self.wsdl = Definitions(url, options) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/wsdl.py", line 194, in __init__ self.build_schema() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/wsdl.py", line 255, in build_schema self.schema = container.load() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 90, in load child.open_imports() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 277, in open_imports imported = imp.open() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 608, in open result = self.download() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 628, in download return self.schema.instance(root, url) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 367, in instance return Schema(root, baseurl, self.options) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 200, in __init__ self.open_imports() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 277, in open_imports imported = imp.open() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 608, in open result = self.download() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 626, in download root = Parser(transport).parse(url=url).root() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/sax/parser.py", line 133, in parse fp = self.transport.open(Request(url)) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/https.py", line 69, in open return HttpTransport.open(self, request) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/http.py", line 69, in open fp = self.__open(u2request) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/http.py", line 107, in __open return self.urlopener.open(u2request) File "/usr/lib/python2.6/urllib2.py", line 391, in open response = self._open(req, data) File "/usr/lib/python2.6/urllib2.py", line 409, in _open '_open', req) File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain result = func(*args) File "/usr/lib/python2.6/urllib2.py", line 1161, in http_open return self.do_open(httplib.HTTPConnection, req) File "/usr/lib/python2.6/urllib2.py", line 1134, in do_open r = h.getresponse() File "/usr/lib/python2.6/httplib.py", line 986, in getresponse response.begin() File "/usr/lib/python2.6/httplib.py", line 391, in begin version, status, reason = self._read_status() File "/usr/lib/python2.6/httplib.py", line 355, in _read_status raise BadStatusLine(line)
# okay, the problem is why sometimes the client return the exception and most of time return the correct results some minutes later?
Thanks for your time and concentration. Any relay is welcome.
-- Jia Xiaolei
Hi Jia,
If you need a soap client, just use suds and don't bother with rpclib/soaplib. It's just incomplete. Currently, the only advantage of using rpclib as a soap client is its speed and if you need speed that bad, you should not be using soap (or xml) anyway.
Does this answer your question, or is there any more questions hidden in the heap below?
best, burak
On 12/06/11 16:03, 贾晓磊 wrote:
Hi, all:
Recently, I have been do something about python webservice. Above all the methods of python webservice, soaplib is welcome and popular. When using soaplib, some problems puzzled me as follows.
porlbem 1: soaplib provide client-side or not? Usually, I use soaplib as follows:
# file-name: soaplib_server.py: # -*- coding:utf-8 -*-
from soaplib.wsgi_soap import SimpleWSGISoapApp from soaplib.service import soapmethod from soaplib.serializers.clazz import ClassSerializer from soaplib.serializers.primitive import String, Integer, Array, DateTime
class SMS(ClassSerializer): class types: mobile = String content = String
class SMSService(SimpleWSGISoapApp): @soapmethod(String, _returns=Array(SMS)) def get_sms(self,id): sms_lst = [] sms = SMS() sms.mobile = "13011292217" sms.content = "hi, it's a test!" sms_lst.append(sms) return sms_lst
def make_client(): from soaplib.client import make_service_client client = make_service_client('http://localhost:7789/' ,SMSService()) return client
if __name__=='__main__': try: from wsgiref.simple_server import make_server server = make_server('localhost', 7789,SMSService()) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
#file-name: suds_client.py import suds
def test_soaplib3(): import logging logging.basicConfig(level=logging.ERROR)
url = "http://localhost:7789/?wsdl" client = suds.client.Client(url,cache=None) print 'client', client output = client.service.get_sms('jia') print 'output', output
#NOTE: Certainly, it's okay. Below is the output:
#output: client Suds ( https://fedorahosted.org/suds/ ) version: 0.3.7 GA build: R580-20091016
Service ( SMSService ) tns="SMSService.SMSService" Prefixes (1) ns0 = "SMSService.SMSService" Ports (1): (SMSService) Methods (1): get_sms(xs:string id, ) Types (4): SMS SMSArray get_sms get_smsResponse
output (SMSArray){ _type = "tns:SMSArray" SMS[] = (SMS){ content = "hi, it's a test!" mobile = "13011292217" }, }
#NOTE: do you find the "def make_client():" in the server-side ? It's no use when we use suds_client.py. Now, let me talk the problem: I think soaplib is only a server-side and without client, you also can find the words as follows in "http://soaplib.github.com/soaplib/2_0/": "Soaplib is an easy to use Python library for publishing SOAP web services using WSDL 1.1 standard, and answering SOAP 1.1 requests. With a very small amount of code, soaplib allows you to write a useful web service and deploy it as a WSGI application. (Non-WSGI scenarios are also supported.)" Most of scenes, soaplib make as server and suds did for client. They can work together well. In a web page, I found someone use client by soaplib, the client can be write as follows:
# file-name: soaplib_client.py # -*- coding:utf-8 -*-
from soaplib_server3 import SMSService from soaplib_server3 import make_client import lxml.etree as et
a = make_client() ret = a.get_sms('jia') print 'ret:', ret print 'type of ret:', type(ret) for i,r in enumerate(ret): print 'i:',i, r.mobile, r.content
#output: ret: [<soaplib_server3.SMS object at 0x8ecf7ec>] type of ret: <type 'list'> i: 0 13011292217 hi, it's a test!
#NOTE: now, the questions are : 1: Whether soaplib can provide client? 2: If the answer for question 1 is okay, then the second question is : how to provide a webservice client using soaplib? Is the method "client = make_service_client('http://localhost:7789/' ,SMSService())" which is be used in my soaplib_serve.py? 3: if you agree that soaplib can make as websevice client-side, I would like to ask: The client relays so heavily on sever-side, in the client-side, it requests some classes or modules in server side are imported. If we use soaplib-client to invoke a remote server(it may be developed in Java, C#, php or other language, or python which is not in the some local), how we get the class in server?
I do not whether i speak my question clearly. In actual fact, what I eager to know is how to provide a client-side using soaplib if soaplib can.
part 2: Is there someone find it spend much time and not stable to invoke soaplib using suds as follows. #NOTE: the code can also be found in "http://soaplib.github.com/soaplib/2_0/pages/helloworld.html" # soaplib_server.py import soaplib from soaplib.core.service import soap from soaplib.core.service import rpc, DefinitionBase from soaplib.core.model.primitive import String, Integer from soaplib.core.server import wsgi from soaplib.core.model.clazz import Array from soaplib.core import Application class HelloWorldService(DefinitionBase):
@soap(String,Integer,_returns=Array(String)) def say_hello(self,name,times): results = [] for i in range(0,times): results.append('Hello, %s'%name) return results
if __name__=='__main__': print 'server begin running...' try: from wsgiref.simple_server import make_server soap_application = Application([HelloWorldService], 'tns')
wsgi_application = wsgi.Application(soap_application) server = make_server('localhost', 7789, wsgi_application) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
# suds.py import suds def test_soaplib():
url = "http://localhost:7789/?wsdl" client = suds.client.Client(url,cache=None) print 'client', client output = client.service.say_hello('jia',3) print 'output', output
when you invoke sus.py , it takes much time and a long time later returns the right result ”output (stringArray){ string[] = "Hello, jia", "Hello, jia", "Hello, jia", } “ or the exception below(it‘s not present exceptions as follows. most of time it return the result successfully after 2 or 3 minutes).
Traceback (most recent call last): File "suds_client.py", line 774, in <module> test_soaplib() File "suds_client.py", line 627, in test_soaplib client = suds.client.Client(url,cache=None) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/client.py", line 109, in __init__ self.wsdl = Definitions(url, options) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/wsdl.py", line 194, in __init__ self.build_schema() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/wsdl.py", line 255, in build_schema self.schema = container.load() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 90, in load child.open_imports() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 277, in open_imports imported = imp.open() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 608, in open result = self.download() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 628, in download return self.schema.instance(root, url) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 367, in instance return Schema(root, baseurl, self.options) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 200, in __init__ self.open_imports() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 277, in open_imports imported = imp.open() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 608, in open result = self.download() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 626, in download root = Parser(transport).parse(url=url).root() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/sax/parser.py", line 133, in parse fp = self.transport.open(Request(url)) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/https.py", line 69, in open return HttpTransport.open(self, request) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/http.py", line 69, in open fp = self.__open(u2request) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/http.py", line 107, in __open return self.urlopener.open(u2request) File "/usr/lib/python2.6/urllib2.py", line 391, in open response = self._open(req, data) File "/usr/lib/python2.6/urllib2.py", line 409, in _open '_open', req) File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain result = func(*args) File "/usr/lib/python2.6/urllib2.py", line 1161, in http_open return self.do_open(httplib.HTTPConnection, req) File "/usr/lib/python2.6/urllib2.py", line 1134, in do_open r = h.getresponse() File "/usr/lib/python2.6/httplib.py", line 986, in getresponse response.begin() File "/usr/lib/python2.6/httplib.py", line 391, in begin version, status, reason = self._read_status() File "/usr/lib/python2.6/httplib.py", line 355, in _read_status raise BadStatusLine(line)
# okay, the problem is why sometimes the client return the exception and most of time return the correct results some minutes later?
Thanks for your time and concentration. Any relay is welcome.
-- Jia Xiaolei
Soap mailing list Soap@python.org http://mail.python.org/mailman/listinfo/soap
Hi Burak,
Thanks much for your replay.
part 1: What you want to said is below, is not it?
1: soaplib work as client is incomplete. A good choice for webservice client is suds. 2: "Currently, the only advantage of using rpclib as a soap client is its speed and if you need speed that bad, you should not be using soap (or xml) anyway.", do you mean that soap is slow and we did nothing about it.
part 2: "Does this answer your question, or is there any more", In fact, i want to know why sometimes suds throws a stack of exceptions when invoke soaplib sever. I have to admire most of time it's okay and wastes longer time. The details is reported in problem 2 of my mail.
part 3: Do you have some experience about Java Axis2? I developed a webservice server-side using tornadows(tornadow webservice.Besides soaplib, tornadows is the best server-side I have meet). I use suds-client invoke tornadows-server successfully. While, if i use Java Axis2 invoke it, nothing happened and the request nearly not reach the server.
In actual fact, how to invoke a webservice server-side successfully is my true question. What I need is provide a python webservice server-side which can be invoked by Java Axis2. This is why i try to find a good webservice server-side, including soaplib.
you can see the code in detail:
# server-side: tornadows
import logging
import tornado.httpserver import tornado.ioloop import tornado.web from tornadows import soaphandler from tornadows import webservices from tornadows import xmltypes from tornadows.soaphandler import webservice from tornado.options import define, options
define('mode', default='deploy') define('port', type=int, default=8000) options['logging'].set('warning')
class SMSService(soaphandler.SoapHandler):
@webservice(_params=xmltypes.Integer,_returns=xmltypes.Integer) def getPrice(self,a): return 1987
if __name__ == '__main__': service = [('SMSService',SMSService)] app = webservices.WebService(service) ws = tornado.httpserver.HTTPServer(app)
ws.listen(options.port) logging.warn("SMSService running on: localhost:%d", options.port) tornado.ioloop.IOLoop.instance().start()
# wsdl: you can find it in web browser through the url “ http://172.16.2.46:8000/SMSService?wsdl%E2%80%9D
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://127.0.1.1:8000/SMSService/getPrice"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd=" http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="SMSService"
targetNamespace="http://127.0.1.1:8000/SMSService/getPrice%22%3E wsdl:types <xsd:schema targetNamespace="http://127.0.1.1:8000/SMSService/getPrice%22%3E <xsd:complexType name="paramsTypes"> xsd:sequence <xsd:element name="a" type="xsd:integer"/> </xsd:sequence> </xsd:complexType> <xsd:element name="params" type="tns:paramsTypes"/> <xsd:element name="returns" type="xsd:integer"/> </xsd:schema> </wsdl:types> <wsdl:message name="SMSServiceRequest"> <wsdl:part element="tns:params" name="parameters"/> </wsdl:message> <wsdl:message name="SMSServiceResponse"> <wsdl:part element="tns:returns" name="parameters"/> </wsdl:message> <wsdl:portType name="SMSServicePortType"> <wsdl:operation name="getPrice"> <wsdl:input message="tns:SMSServiceRequest"/> <wsdl:output message="tns:SMSServiceResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="SMSServiceBinding" type="tns:SMSServicePortType"> <soap:binding style="document" transport=" http://schemas.xmlsoap.org/soap/http%22/%3E <wsdl:operation name="getPrice"> <soap:operation soapAction="http://127.0.1.1:8000/SMSService" style="document"/> wsdl:input <soap:body use="literal"/> </wsdl:input> wsdl:output <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="SMSService"> <wsdl:port binding="tns:SMSServiceBinding" name="SMSServicePort"> <soap:address location="http://127.0.1.1:8000/SMSService%22/%3E </wsdl:port> </wsdl:service> </wsdl:definitions>
# client:
package client;
import javax.xml.namespace.QName; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient;
public class client_for_python {
public static void main(String[] args) throws Exception {
// step 1: 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); // step 2: 指定调用WebService的URL // url for python String url2 = "http://172.16.2.46:8000/SMSService"; EndpointReference targetEPR = new EndpointReference(url2); options.setTo(targetEPR); // step 3: 指定getGreeting方法的参数值 // step 5-6: (similiar whit // it!)下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似 Class[] classes = new Class[] { int.class }; QName opAddEntry = new QName( "http://172.16.2.46:8000/SMSService/getPrice"); System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[] {1}, classes)[0]); } } # NOTE: the client get nothing from sever-side and server-side get nothing from Axis2-client.
Apart from it, I made a server-side using soaplib. Still be failed though.
# server-side: soaplib
from soaplib.wsgi_soap import SimpleWSGISoapApp from soaplib.service import soapmethod from soaplib.serializers.clazz import ClassSerializer from soaplib.serializers.primitive import String, Integer, Array, DateTime
class SMSService(SimpleWSGISoapApp): @soapmethod(_returns=Integer) def getPrice(self): return 11
if __name__=='__main__': try: from wsgiref.simple_server import make_server server = make_server('localhost', 7789,SMSService()) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
#wsdl: I cannot get wsdl form web browser, and I get the wsdl using "w3m http//localhost:7789/?wsdl' from the server-side.
<definitions xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/ "
xmlns:tns="SMSService.SMSService" xmlns:typens="SMSService.SMSService"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi=" http://www.w3.org/1999/XMLSchema-
instance" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="SMSService.SMSService"
name="SMSService"> <types> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="SMSService.SMSService"> <xs:element name="getPriceResponse" type="tns:getPriceResponse"/> <xs:complexType name="getPrice"> xs:sequence/ </xs:complexType> <xs:complexType name="getPriceResponse"> xs:sequence <xs:element name="getPriceResult" type="xs:int"/> </xs:sequence> </xs:complexType> <xs:element name="getPrice" type="tns:getPrice"/> </schema> </types> <message name="getPrice"/> <message name="getPriceResponse"> <part name="getPriceResponse" element="tns:getPriceResponse"/> </message> <portType name="SMSService"> <operation name="getPrice" parameterOrder="getPrice"> <documentation/> <input name="getPrice" message="tns:getPrice"/> <output name="getPriceResponse" message="tns:getPriceResponse"/> </operation> </portType> <plnk:partnerLinkType name="SMSService"> <plnk:role name="SMSService"> <plnk:portType name="tns:SMSService"/> </plnk:role> </plnk:partnerLinkType> <binding name="SMSService" type="tns:SMSService"> <soap:binding style="document" transport=" http://schemas.xmlsoap.org/soap/http%22/%3E <operation name="getPrice"> <soap:operation soapAction="getPrice" style="document"/> <input name="getPrice"> <soap:body use="literal"/> </input> <output name="getPriceResponse"> <soap:body use="literal"/> </output> </operation> </binding> <service name="SMSService"> <port name="SMSService" binding="tns:SMSService"> <soap:address location="http://localhost:7789/?wsdl%22/%3E </port> </service> </definitions>
# client: Java Axis2
package client;
import javax.xml.namespace.QName; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient;
public class client_for_python_soaplib {
public static void main(String[] args) throws Exception { // step 1: 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); // step 2: 指定调用WebService的URL // url for python String url2 = "http://172.16.2.46:7789"; EndpointReference targetEPR = new EndpointReference(url2); options.setTo(targetEPR); // step 3: 指定getGreeting方法的参数值 // step 5-6: (similiar whit // it!)下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似 Class[] classes = new Class[] { int.class }; QName opAddEntry = new QName(url2, "SMSService.SMSService"); System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[] {1}, classes)[0]); } }
# output: Exception in thread "main" org.apache.axis2.AxisFault: Connection refused: connect at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:197) at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75) at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:404) at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:231) at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443) at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406) at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229) at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165) at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:555) at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:531) at org.apache.axis2.rpc.client.RPCServiceClient.invokeBlocking(RPCServiceClient.java:102) at client.client_for_python_soaplib.main(client_for_python_soaplib.java:25) Caused by: java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) at java.net.Socket.connect(Socket.java:519) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.commons.httpclient.protocol.ReflectionSocketFactory.createSocket(ReflectionSocketFactory.java:140) at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:125) at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707) at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:621) at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:193) ... 11 more
Thanks ahead for your time and sprit.
-- Jia Xiaolei
On Tue, Dec 6, 2011 at 10:59 PM, Burak Arslan burak.arslan@arskom.com.trwrote:
Hi Jia,
If you need a soap client, just use suds and don't bother with rpclib/soaplib. It's just incomplete. Currently, the only advantage of using rpclib as a soap client is its speed and if you need speed that bad, you should not be using soap (or xml) anyway.
Does this answer your question, or is there any more questions hidden in the heap below?
best, burak
On 12/06/11 16:03, 贾晓磊 wrote:
Hi, all:
Recently, I have been do something about python webservice. Above all the methods of python webservice, soaplib is welcome and popular. When using soaplib, some problems puzzled me as follows.
porlbem 1: soaplib provide client-side or not? Usually, I use soaplib as follows:
# file-name: soaplib_server.py: # -*- coding:utf-8 -*-
from soaplib.wsgi_soap import SimpleWSGISoapApp from soaplib.service import soapmethod from soaplib.serializers.clazz import ClassSerializer from soaplib.serializers.primitive import String, Integer, Array, DateTime
class SMS(ClassSerializer): class types: mobile = String content = String
class SMSService(SimpleWSGISoapApp): @soapmethod(String, _returns=Array(SMS)) def get_sms(self,id): sms_lst = [] sms = SMS() sms.mobile = "13011292217" sms.content = "hi, it's a test!" sms_lst.append(sms) return sms_lst
def make_client(): from soaplib.client import make_service_client client = make_service_client('http://localhost:7789/' ,SMSService()) return client
if __name__=='__main__': try: from wsgiref.simple_server import make_server server = make_server('localhost', 7789,SMSService()) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
#file-name: suds_client.py import suds
def test_soaplib3(): import logging logging.basicConfig(level=logging.ERROR)
url = "http://localhost:7789/?wsdl" client = suds.client.Client(url,cache=None) print 'client', client output = client.service.get_sms('jia') print 'output', output
#NOTE: Certainly, it's okay. Below is the output:
#output: client Suds ( https://fedorahosted.org/suds/ ) version: 0.3.7 GA build: R580-20091016
Service ( SMSService ) tns="SMSService.SMSService" Prefixes (1) ns0 = "SMSService.SMSService" Ports (1): (SMSService) Methods (1): get_sms(xs:string id, ) Types (4): SMS SMSArray get_sms get_smsResponse
output (SMSArray){ _type = "tns:SMSArray" SMS[] = (SMS){ content = "hi, it's a test!" mobile = "13011292217" }, }
#NOTE: do you find the "def make_client():" in the server-side ? It's no use when we use suds_client.py. Now, let me talk the problem: I think soaplib is only a server-side and without client, you also can find the words as follows in "http://soaplib.github.com/soaplib/2_0/": "Soaplib is an easy to use Python library for publishing SOAP web services using WSDL 1.1 standard, and answering SOAP 1.1 requests. With a very small amount of code, soaplib allows you to write a useful web service and deploy it as a WSGI application. (Non-WSGI scenarios are also supported.)" Most of scenes, soaplib make as server and suds did for client. They can work together well. In a web page, I found someone use client by soaplib, the client can be write as follows:
# file-name: soaplib_client.py # -*- coding:utf-8 -*-
from soaplib_server3 import SMSService from soaplib_server3 import make_client import lxml.etree as et
a = make_client() ret = a.get_sms('jia') print 'ret:', ret print 'type of ret:', type(ret) for i,r in enumerate(ret): print 'i:',i, r.mobile, r.content
#output: ret: [<soaplib_server3.SMS object at 0x8ecf7ec>] type of ret: <type 'list'> i: 0 13011292217 hi, it's a test!
#NOTE: now, the questions are : 1: Whether soaplib can provide client? 2: If the answer for question 1 is okay, then the second question is : how to provide a webservice client using soaplib? Is the method "client = make_service_client('http://localhost:7789/' ,SMSService())" which is be used in my soaplib_serve.py? 3: if you agree that soaplib can make as websevice client-side, I would like to ask: The client relays so heavily on sever-side, in the client-side, it requests some classes or modules in server side are imported. If we use soaplib-client to invoke a remote server(it may be developed in Java, C#, php or other language, or python which is not in the some local), how we get the class in server?
I do not whether i speak my question clearly. In actual fact, what I eager to know is how to provide a client-side using soaplib if soaplib can.
part 2: Is there someone find it spend much time and not stable to invoke soaplib using suds as follows. #NOTE: the code can also be found in " http://soaplib.github.com/soaplib/2_0/pages/helloworld.html" # soaplib_server.py import soaplib from soaplib.core.service import soap from soaplib.core.service import rpc, DefinitionBase from soaplib.core.model.primitive import String, Integer from soaplib.core.server import wsgi from soaplib.core.model.clazz import Array from soaplib.core import Application class HelloWorldService(DefinitionBase):
@soap(String,Integer,_returns=Array(String)) def say_hello(self,name,times): results = [] for i in range(0,times): results.append('Hello, %s'%name) return results
if __name__=='__main__': print 'server begin running...' try: from wsgiref.simple_server import make_server soap_application = Application([HelloWorldService], 'tns')
wsgi_application = wsgi.Application(soap_application) server = make_server('localhost', 7789, wsgi_application) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
# suds.py import suds def test_soaplib():
url = "http://localhost:7789/?wsdl" client = suds.client.Client(url,cache=None) print 'client', client output = client.service.say_hello('jia',3) print 'output', output
when you invoke sus.py , it takes much time and a long time later returns the right result ”output (stringArray){ string[] = "Hello, jia", "Hello, jia", "Hello, jia", } “ or the exception below(it‘s not present exceptions as follows. most of time it return the result successfully after 2 or 3 minutes).
Traceback (most recent call last): File "suds_client.py", line 774, in <module> test_soaplib() File "suds_client.py", line 627, in test_soaplib client = suds.client.Client(url,cache=None) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/client.py", line 109, in __init__ self.wsdl = Definitions(url, options) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/wsdl.py", line 194, in __init__ self.build_schema() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/wsdl.py", line 255, in build_schema self.schema = container.load() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 90, in load child.open_imports() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 277, in open_imports imported = imp.open() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 608, in open result = self.download() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 628, in download return self.schema.instance(root, url) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 367, in instance return Schema(root, baseurl, self.options) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 200, in __init__ self.open_imports() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 277, in open_imports imported = imp.open() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 608, in open result = self.download() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 626, in download root = Parser(transport).parse(url=url).root() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/sax/parser.py", line 133, in parse fp = self.transport.open(Request(url)) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/https.py", line 69, in open return HttpTransport.open(self, request) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/http.py", line 69, in open fp = self.__open(u2request) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/http.py", line 107, in __open return self.urlopener.open(u2request) File "/usr/lib/python2.6/urllib2.py", line 391, in open response = self._open(req, data) File "/usr/lib/python2.6/urllib2.py", line 409, in _open '_open', req) File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain result = func(*args) File "/usr/lib/python2.6/urllib2.py", line 1161, in http_open return self.do_open(httplib.HTTPConnection, req) File "/usr/lib/python2.6/urllib2.py", line 1134, in do_open r = h.getresponse() File "/usr/lib/python2.6/httplib.py", line 986, in getresponse response.begin() File "/usr/lib/python2.6/httplib.py", line 391, in begin version, status, reason = self._read_status() File "/usr/lib/python2.6/httplib.py", line 355, in _read_status raise BadStatusLine(line)
# okay, the problem is why sometimes the client return the exception and most of time return the correct results some minutes later?
Thanks for your time and concentration. Any relay is welcome.
-- Jia Xiaolei
Soap mailing listSoap@python.orghttp://mail.python.org/mailman/listinfo/soap
Hi Burak,
Thanks much for your replay.
part 1: What you want to said is below, is not it?
1: soaplib work as client is incomplete. A good choice for webservice client is suds. 2: "Currently, the only advantage of using rpclib as a soap client is its speed and if you need speed that bad, you should not be using soap (or xml) anyway.", do you mean that soap is slow and we did nothing about it.
part 2: "Does this answer your question, or is there any more", In fact, i want to know why sometimes suds throws a stack of exceptions when invoke soaplib sever. I have to admire most of time it's okay and wastes longer time. The details is reported in problem 2 of my mail.
part 3: Do you have some experience about Java Axis2? I developed a webservice server-side using tornadows(tornadow webservice.Besides soaplib, tornadows is the best server-side I have meet). I use suds-client invoke tornadows-server successfully. While, if i use Java Axis2 invoke it, nothing happened and the request nearly not reach the server.
In actual fact, how to invoke a webservice server-side successfully is my true question. What I need is provide a python webservice server-side which can be invoked by Java Axis2. This is why i try to find a good webservice server-side, including soaplib.
you can see the code in detail:
# server-side: tornadows
import logging
import tornado.httpserver import tornado.ioloop import tornado.web from tornadows import soaphandler from tornadows import webservices from tornadows import xmltypes from tornadows.soaphandler import webservice from tornado.options import define, options
define('mode', default='deploy') define('port', type=int, default=8000) options['logging'].set('warning')
class SMSService(soaphandler.SoapHandler):
@webservice(_params=xmltypes.Integer,_returns=xmltypes.Integer) def getPrice(self,a): return 1987
if __name__ == '__main__': service = [('SMSService',SMSService)] app = webservices.WebService(service) ws = tornado.httpserver.HTTPServer(app)
ws.listen(options.port) logging.warn("SMSService running on: localhost:%d", options.port) tornado.ioloop.IOLoop.instance().start()
# wsdl: you can find it in web browser through the url “ http://172.16.2.46:8000/SMSService?wsdl%E2%80%9D
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://127.0.1.1:8000/SMSService/getPrice" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd=" http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="SMSService" targetNamespace="http://127.0.1.1:8000/SMSService/getPrice%22%3E wsdl:types <xsd:schema targetNamespace="http://127.0.1.1:8000/SMSService/getPrice%22%3E <xsd:complexType name="paramsTypes"> xsd:sequence <xsd:element name="a" type="xsd:integer"/> </xsd:sequence> </xsd:complexType> <xsd:element name="params" type="tns:paramsTypes"/> <xsd:element name="returns" type="xsd:integer"/> </xsd:schema> </wsdl:types> <wsdl:message name="SMSServiceRequest"> <wsdl:part element="tns:params" name="parameters"/> </wsdl:message> <wsdl:message name="SMSServiceResponse"> <wsdl:part element="tns:returns" name="parameters"/> </wsdl:message> <wsdl:portType name="SMSServicePortType"> <wsdl:operation name="getPrice"> <wsdl:input message="tns:SMSServiceRequest"/> <wsdl:output message="tns:SMSServiceResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="SMSServiceBinding" type="tns:SMSServicePortType"> <soap:binding style="document" transport=" http://schemas.xmlsoap.org/soap/http%22/%3E <wsdl:operation name="getPrice"> <soap:operation soapAction="http://127.0.1.1:8000/SMSService" style="document"/> wsdl:input <soap:body use="literal"/> </wsdl:input> wsdl:output <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="SMSService"> <wsdl:port binding="tns:SMSServiceBinding" name="SMSServicePort"> <soap:address location="http://127.0.1.1:8000/SMSService%22/%3E </wsdl:port> </wsdl:service> </wsdl:definitions>
# client:
package client;
import javax.xml.namespace.QName; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient;
public class client_for_python {
public static void main(String[] args) throws Exception {
// step 1: 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); // step 2: 指定调用WebService的URL // url for python String url2 = "http://172.16.2.46:8000/SMSService"; EndpointReference targetEPR = new EndpointReference(url2); options.setTo(targetEPR); // step 3: 指定getGreeting方法的参数值 // step 5-6: (similiar whit // it!)下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似 Class[] classes = new Class[] { int.class }; QName opAddEntry = new QName( "http://172.16.2.46:8000/SMSService/getPrice"); System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[] {1}, classes)[0]); } } # NOTE: the client get nothing from sever-side and server-side get nothing from Axis2-client.
Apart from it, I made a server-side using soaplib. Still be failed though.
# server-side: soaplib
from soaplib.wsgi_soap import SimpleWSGISoapApp from soaplib.service import soapmethod from soaplib.serializers.clazz import ClassSerializer from soaplib.serializers.primitive import String, Integer, Array, DateTime
class SMSService(SimpleWSGISoapApp): @soapmethod(_returns=Integer) def getPrice(self): return 11
if __name__=='__main__': try: from wsgiref.simple_server import make_server server = make_server('localhost', 7789,SMSService()) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
#wsdl: I cannot get wsdl form web browser, and I get the wsdl using "w3m http//localhost:7789/?wsdl' from the server-side.
<definitions xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/ " xmlns:tns="SMSService.SMSService" xmlns:typens="SMSService.SMSService" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi=" http://www.w3.org/1999/XMLSchema- instance" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="SMSService.SMSService" name="SMSService"> <types> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="SMSService.SMSService"> <xs:element name="getPriceResponse" type="tns:getPriceResponse"/> <xs:complexType name="getPrice"> xs:sequence/ </xs:complexType> <xs:complexType name="getPriceResponse"> xs:sequence <xs:element name="getPriceResult" type="xs:int"/> </xs:sequence> </xs:complexType> <xs:element name="getPrice" type="tns:getPrice"/> </schema> </types> <message name="getPrice"/> <message name="getPriceResponse"> <part name="getPriceResponse" element="tns:getPriceResponse"/> </message> <portType name="SMSService"> <operation name="getPrice" parameterOrder="getPrice"> <documentation/> <input name="getPrice" message="tns:getPrice"/> <output name="getPriceResponse" message="tns:getPriceResponse"/> </operation> </portType> <plnk:partnerLinkType name="SMSService"> <plnk:role name="SMSService"> <plnk:portType name="tns:SMSService"/> </plnk:role> </plnk:partnerLinkType> <binding name="SMSService" type="tns:SMSService"> <soap:binding style="document" transport=" http://schemas.xmlsoap.org/soap/http%22/%3E <operation name="getPrice"> <soap:operation soapAction="getPrice" style="document"/> <input name="getPrice"> <soap:body use="literal"/> </input> <output name="getPriceResponse"> <soap:body use="literal"/> </output> </operation> </binding> <service name="SMSService"> <port name="SMSService" binding="tns:SMSService"> <soap:address location="http://localhost:7789/?wsdl%22/%3E </port> </service> </definitions>
# client: Java Axis2
package client;
import javax.xml.namespace.QName; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient;
public class client_for_python_soaplib {
public static void main(String[] args) throws Exception { // step 1: 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); // step 2: 指定调用WebService的URL // url for python String url2 = "http://172.16.2.46:7789"; EndpointReference targetEPR = new EndpointReference(url2); options.setTo(targetEPR); // step 3: 指定getGreeting方法的参数值 // step 5-6: (similiar whit // it!)下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似 Class[] classes = new Class[] { int.class }; QName opAddEntry = new QName(url2, "SMSService.SMSService"); System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[] {1}, classes)[0]); } }
# output: Exception in thread "main" org.apache.axis2.AxisFault: Connection refused: connect at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:197) at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75) at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:404) at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:231) at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443) at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406) at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229) at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165) at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:555) at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:531) at org.apache.axis2.rpc.client.RPCServiceClient.invokeBlocking(RPCServiceClient.java:102) at client.client_for_python_soaplib.main(client_for_python_soaplib.java:25) Caused by: java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) at java.net.Socket.connect(Socket.java:519) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.commons.httpclient.protocol.ReflectionSocketFactory.createSocket(ReflectionSocketFactory.java:140) at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:125) at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707) at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:621) at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:193) ... 11 more
Thanks ahead for your time and sprit.
-- Jia Xiaolei
On Tue, Dec 6, 2011 at 10:59 PM, Burak Arslan burak.arslan@arskom.com.trwrote:
Hi Jia,
If you need a soap client, just use suds and don't bother with rpclib/soaplib. It's just incomplete. Currently, the only advantage of using rpclib as a soap client is its speed and if you need speed that bad, you should not be using soap (or xml) anyway.
Does this answer your question, or is there any more questions hidden in the heap below?
best, burak
On 12/06/11 16:03, 贾晓磊 wrote:
Hi, all:
Recently, I have been do something about python webservice. Above all the methods of python webservice, soaplib is welcome and popular. When using soaplib, some problems puzzled me as follows.
porlbem 1: soaplib provide client-side or not? Usually, I use soaplib as follows:
# file-name: soaplib_server.py: # -*- coding:utf-8 -*-
from soaplib.wsgi_soap import SimpleWSGISoapApp from soaplib.service import soapmethod from soaplib.serializers.clazz import ClassSerializer from soaplib.serializers.primitive import String, Integer, Array, DateTime
class SMS(ClassSerializer): class types: mobile = String content = String
class SMSService(SimpleWSGISoapApp): @soapmethod(String, _returns=Array(SMS)) def get_sms(self,id): sms_lst = [] sms = SMS() sms.mobile = "13011292217" sms.content = "hi, it's a test!" sms_lst.append(sms) return sms_lst
def make_client(): from soaplib.client import make_service_client client = make_service_client('http://localhost:7789/' ,SMSService()) return client
if __name__=='__main__': try: from wsgiref.simple_server import make_server server = make_server('localhost', 7789,SMSService()) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
#file-name: suds_client.py import suds
def test_soaplib3(): import logging logging.basicConfig(level=logging.ERROR)
url = "http://localhost:7789/?wsdl" client = suds.client.Client(url,cache=None) print 'client', client output = client.service.get_sms('jia') print 'output', output
#NOTE: Certainly, it's okay. Below is the output:
#output: client Suds ( https://fedorahosted.org/suds/ ) version: 0.3.7 GA build: R580-20091016
Service ( SMSService ) tns="SMSService.SMSService" Prefixes (1) ns0 = "SMSService.SMSService" Ports (1): (SMSService) Methods (1): get_sms(xs:string id, ) Types (4): SMS SMSArray get_sms get_smsResponse
output (SMSArray){ _type = "tns:SMSArray" SMS[] = (SMS){ content = "hi, it's a test!" mobile = "13011292217" }, }
#NOTE: do you find the "def make_client():" in the server-side ? It's no use when we use suds_client.py. Now, let me talk the problem: I think soaplib is only a server-side and without client, you also can find the words as follows in "http://soaplib.github.com/soaplib/2_0/": "Soaplib is an easy to use Python library for publishing SOAP web services using WSDL 1.1 standard, and answering SOAP 1.1 requests. With a very small amount of code, soaplib allows you to write a useful web service and deploy it as a WSGI application. (Non-WSGI scenarios are also supported.)" Most of scenes, soaplib make as server and suds did for client. They can work together well. In a web page, I found someone use client by soaplib, the client can be write as follows:
# file-name: soaplib_client.py # -*- coding:utf-8 -*-
from soaplib_server3 import SMSService from soaplib_server3 import make_client import lxml.etree as et
a = make_client() ret = a.get_sms('jia') print 'ret:', ret print 'type of ret:', type(ret) for i,r in enumerate(ret): print 'i:',i, r.mobile, r.content
#output: ret: [<soaplib_server3.SMS object at 0x8ecf7ec>] type of ret: <type 'list'> i: 0 13011292217 hi, it's a test!
#NOTE: now, the questions are : 1: Whether soaplib can provide client? 2: If the answer for question 1 is okay, then the second question is : how to provide a webservice client using soaplib? Is the method "client = make_service_client('http://localhost:7789/' ,SMSService())" which is be used in my soaplib_serve.py? 3: if you agree that soaplib can make as websevice client-side, I would like to ask: The client relays so heavily on sever-side, in the client-side, it requests some classes or modules in server side are imported. If we use soaplib-client to invoke a remote server(it may be developed in Java, C#, php or other language, or python which is not in the some local), how we get the class in server?
I do not whether i speak my question clearly. In actual fact, what I eager to know is how to provide a client-side using soaplib if soaplib can.
part 2: Is there someone find it spend much time and not stable to invoke soaplib using suds as follows. #NOTE: the code can also be found in " http://soaplib.github.com/soaplib/2_0/pages/helloworld.html" # soaplib_server.py import soaplib from soaplib.core.service import soap from soaplib.core.service import rpc, DefinitionBase from soaplib.core.model.primitive import String, Integer from soaplib.core.server import wsgi from soaplib.core.model.clazz import Array from soaplib.core import Application class HelloWorldService(DefinitionBase):
@soap(String,Integer,_returns=Array(String)) def say_hello(self,name,times): results = [] for i in range(0,times): results.append('Hello, %s'%name) return results
if __name__=='__main__': print 'server begin running...' try: from wsgiref.simple_server import make_server soap_application = Application([HelloWorldService], 'tns')
wsgi_application = wsgi.Application(soap_application) server = make_server('localhost', 7789, wsgi_application) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
# suds.py import suds def test_soaplib():
url = "http://localhost:7789/?wsdl" client = suds.client.Client(url,cache=None) print 'client', client output = client.service.say_hello('jia',3) print 'output', output
when you invoke sus.py , it takes much time and a long time later returns the right result ”output (stringArray){ string[] = "Hello, jia", "Hello, jia", "Hello, jia", } “ or the exception below(it‘s not present exceptions as follows. most of time it return the result successfully after 2 or 3 minutes).
Traceback (most recent call last): File "suds_client.py", line 774, in <module> test_soaplib() File "suds_client.py", line 627, in test_soaplib client = suds.client.Client(url,cache=None) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/client.py", line 109, in __init__ self.wsdl = Definitions(url, options) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/wsdl.py", line 194, in __init__ self.build_schema() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/wsdl.py", line 255, in build_schema self.schema = container.load() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 90, in load child.open_imports() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 277, in open_imports imported = imp.open() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 608, in open result = self.download() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 628, in download return self.schema.instance(root, url) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 367, in instance return Schema(root, baseurl, self.options) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 200, in __init__ self.open_imports() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/schema.py", line 277, in open_imports imported = imp.open() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 608, in open result = self.download() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/xsd/sxbasic.py", line 626, in download root = Parser(transport).parse(url=url).root() File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/sax/parser.py", line 133, in parse fp = self.transport.open(Request(url)) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/https.py", line 69, in open return HttpTransport.open(self, request) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/http.py", line 69, in open fp = self.__open(u2request) File "/usr/local/lib/python2.6/dist-packages/suds-0.3.7-py2.6.egg/suds/transport/http.py", line 107, in __open return self.urlopener.open(u2request) File "/usr/lib/python2.6/urllib2.py", line 391, in open response = self._open(req, data) File "/usr/lib/python2.6/urllib2.py", line 409, in _open '_open', req) File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain result = func(*args) File "/usr/lib/python2.6/urllib2.py", line 1161, in http_open return self.do_open(httplib.HTTPConnection, req) File "/usr/lib/python2.6/urllib2.py", line 1134, in do_open r = h.getresponse() File "/usr/lib/python2.6/httplib.py", line 986, in getresponse response.begin() File "/usr/lib/python2.6/httplib.py", line 391, in begin version, status, reason = self._read_status() File "/usr/lib/python2.6/httplib.py", line 355, in _read_status raise BadStatusLine(line)
# okay, the problem is why sometimes the client return the exception and most of time return the correct results some minutes later?
Thanks for your time and concentration. Any relay is welcome.
-- Jia Xiaolei
Soap mailing listSoap@python.orghttp://mail.python.org/mailman/listinfo/soap
On 12/07/11 07:51, 贾晓磊 wrote:
Exception in thread "main" org.apache.axis2.AxisFault: Connection refused: connect
I think this speaks enough for itself. You don't even read what you're sending us, so why should we?
Burak
Exception in thread "main" org.apache.axis2.AxisFault: Connection
refused: connect
I think this speaks enough for itself. You don't even read what you're sending us, so why should we?
Burak
Hi, Burak:
I certainly read what I sent.
In part 1, serve-side is tornadows, the axis2-client cannot invoke the server, and returns nothing
In part 2, server-side is soaplib. the server is developed in ubuntu linux,"172.16.2.46" is its ip, when you exceute "w3m http://localhost:7789/?wsdl", "w3m http://127.0.0.1:7789/?wsdl", thay are okay. but "w3m: Can't load http://172.16.2.46:7789/?wsdl." is failed. I develop tornadows in the same ubuntu linux, "w3m http://172.16.2.46:8000/SMSService?wsdl" is also okay. In the local area network, "http://172.16.2.46:8000/SMSService?wsdl" is also okay. I do not know the difference of tornadows and soaplib, so sent them together.
w_jiaxiaolei@pabb-608:~$ ifconfig eth0 Link encap:Ethernet HWaddr 1c:6f:65:d4:b3:d3 inet addr:172.16.2.46 Bcast:172.16.255.255 Mask:255.255.0.0 inet6 addr: fe80::1e6f:65ff:fed4:b3d3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2538292 errors:0 dropped:0 overruns:0 frame:0 TX packets:979243 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:276531149 (276.5 MB) TX bytes:621990155 (621.9 MB) Interrupt:32 Base address:0xa000
lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:2619 errors:0 dropped:0 overruns:0 frame:0 TX packets:2619 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:410554 (410.5 KB) TX bytes:410554 (410.5 KB)
w_jiaxiaolei@pabb-608:~$ w3m http://172.16.2.46:8000/SMSService?wsdl w_jiaxiaolei@pabb-608:~$ w3m http://127.0.0.1:7789/?wsdl w_jiaxiaolei@pabb-608:~$ w3m http://localhost:7789/?wsdl w_jiaxiaolei@pabb-608:~$ w3m http://172.16.2.46:7789/?wsdl w3m: Can't load http://172.16.2.46:7789/?wsdl.
Okay, now let's forget part 2, look at part 1 only. How to invoke a python webservice server-side(tornadow, soaplib, or others) using Axis2?
------------------------------ part 1----------------------------- # server-side: tornadows
import logging
import tornado.httpserver import tornado.ioloop import tornado.web from tornadows import soaphandler from tornadows import webservices from tornadows import xmltypes from tornadows.soaphandler import webservice from tornado.options import define, options
define('mode', default='deploy') define('port', type=int, default=8000) options['logging'].set('warning')
class SMSService(soaphandler.SoapHandler):
@webservice(_params=xmltypes.Integer,_returns=xmltypes.Integer) def getPrice(self,a): return 1987
if __name__ == '__main__': service = [('SMSService',SMSService)] app = webservices.WebService(service) ws = tornado.httpserver.HTTPServer(app)
ws.listen(options.port) logging.warn("SMSService running on: localhost:%d", options.port) tornado.ioloop.IOLoop.instance().start()
# wsdl: you can find it in web browser through the url “ http://172.16.2.46:8000/SMSService?wsdl%E2%80%9D
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://127.0.1.1:8000/SMSService/getPrice" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd=" http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="SMSService" targetNamespace="http://127.0.1.1:8000/SMSService/getPrice%22%3E wsdl:types <xsd:schema targetNamespace="http://127.0.1.1:8000/SMSService/getPrice%22%3E <xsd:complexType name="paramsTypes"> xsd:sequence <xsd:element name="a" type="xsd:integer"/> </xsd:sequence> </xsd:complexType> <xsd:element name="params" type="tns:paramsTypes"/> <xsd:element name="returns" type="xsd:integer"/> </xsd:schema> </wsdl:types> <wsdl:message name="SMSServiceRequest"> <wsdl:part element="tns:params" name="parameters"/> </wsdl:message> <wsdl:message name="SMSServiceResponse"> <wsdl:part element="tns:returns" name="parameters"/> </wsdl:message> <wsdl:portType name="SMSServicePortType"> <wsdl:operation name="getPrice"> <wsdl:input message="tns:SMSServiceRequest"/> <wsdl:output message="tns:SMSServiceResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="SMSServiceBinding" type="tns:SMSServicePortType"> <soap:binding style="document" transport=" http://schemas.xmlsoap.org/soap/http%22/%3E <wsdl:operation name="getPrice"> <soap:operation soapAction="http://127.0.1.1:8000/SMSService" style="document"/> wsdl:input <soap:body use="literal"/> </wsdl:input> wsdl:output <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="SMSService"> <wsdl:port binding="tns:SMSServiceBinding" name="SMSServicePort"> <soap:address location="http://127.0.1.1:8000/SMSService%22/%3E </wsdl:port> </wsdl:service> </wsdl:definitions>
# client:
package client;
import javax.xml.namespace.QName; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient;
public class client_for_python {
public static void main(String[] args) throws Exception {
// step 1: 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); // step 2: 指定调用WebService的URL // url for python String url2 = "http://172.16.2.46:8000/SMSService"; EndpointReference targetEPR = new EndpointReference(url2); options.setTo(targetEPR); // step 3: 指定getGreeting方法的参数值 // step 5-6: (similiar whit // it!)下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似 Class[] classes = new Class[] { int.class }; QName opAddEntry = new QName( "http://172.16.2.46:8000/SMSService/getPrice"); System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[] {1}, classes)[0]); } } # NOTE: the client get nothing from sever-side and server-side get nothing from Axis2-client.
------------------------------- part 2 --------------------------------------------
Apart from it, I made a server-side using soaplib. Still be failed though.
# server-side: soaplib
from soaplib.wsgi_soap import SimpleWSGISoapApp from soaplib.service import soapmethod from soaplib.serializers.clazz import ClassSerializer from soaplib.serializers.primitive import String, Integer, Array, DateTime
class SMSService(SimpleWSGISoapApp): @soapmethod(_returns=Integer) def getPrice(self): return 11
if __name__=='__main__': try: from wsgiref.simple_server import make_server server = make_server('localhost', 7789,SMSService()) server.serve_forever() except ImportError: print "Error: example server code requires Python >= 2.5"
#wsdl:* I cannot get wsdl form web browser, and I get the wsdl using "w3m http//localhost:7789/?wsdl' from the server-side.*
<definitions xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/ " xmlns:tns="SMSService.SMSService" xmlns:typens="SMSService.SMSService" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi=" http://www.w3.org/1999/XMLSchema- instance" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="SMSService.SMSService" name="SMSService"> <types> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="SMSService.SMSService"> <xs:element name="getPriceResponse" type="tns:getPriceResponse"/> <xs:complexType name="getPrice"> xs:sequence/ </xs:complexType> <xs:complexType name="getPriceResponse"> xs:sequence <xs:element name="getPriceResult" type="xs:int"/> </xs:sequence> </xs:complexType> <xs:element name="getPrice" type="tns:getPrice"/> </schema> </types> <message name="getPrice"/> <message name="getPriceResponse"> <part name="getPriceResponse" element="tns:getPriceResponse"/> </message> <portType name="SMSService"> <operation name="getPrice" parameterOrder="getPrice"> <documentation/> <input name="getPrice" message="tns:getPrice"/> <output name="getPriceResponse" message="tns:getPriceResponse"/> </operation> </portType> <plnk:partnerLinkType name="SMSService"> <plnk:role name="SMSService"> <plnk:portType name="tns:SMSService"/> </plnk:role> </plnk:partnerLinkType> <binding name="SMSService" type="tns:SMSService"> <soap:binding style="document" transport=" http://schemas.xmlsoap.org/soap/http%22/%3E <operation name="getPrice"> <soap:operation soapAction="getPrice" style="document"/> <input name="getPrice"> <soap:body use="literal"/> </input> <output name="getPriceResponse"> <soap:body use="literal"/> </output> </operation> </binding> <service name="SMSService"> <port name="SMSService" binding="tns:SMSService"> <soap:address location="http://localhost:7789/?wsdl%22/%3E </port> </service> </definitions>
# client: Java Axis2
package client;
import javax.xml.namespace.QName; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient;
public class client_for_python_soaplib {
public static void main(String[] args) throws Exception { // step 1: 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); // step 2: 指定调用WebService的URL // url for python String url2 = "http://172.16.2.46:7789"; EndpointReference targetEPR = new EndpointReference(url2); options.setTo(targetEPR); // step 3: 指定getGreeting方法的参数值 // step 5-6: (similiar whit // it!)下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似 Class[] classes = new Class[] { int.class }; QName opAddEntry = new QName(url2, "SMSService.SMSService"); System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[] {1}, classes)[0]); } }
# output: Exception in thread "main" org.apache.axis2.AxisFault: Connection refused: connect at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:197) ...
-- Jia Xiaolei
On 07.12.2011 12:02, 贾晓磊 wrote:
Exception in thread "main" org.apache.axis2.AxisFault: Connection
> refused: connect I think this speaks enough for itself. You don't even read what you're sending us, so why should we? Burak
Hi, Burak:
I certainly read what I sent.
hi jia,
"connection refused" is not a soap error. please have it working before asking soap-related questions.
best, burak
Burak Arslan wrote at 2011-12-7 18:56 +0200:
On 07.12.2011 12:02, ??? wrote: ... "connection refused" is not a soap error. please have it working before asking soap-related questions.
"connection refused" means that there is no server listening.
This, you must ensure the server has started successfully (and kept running).
-- Dieter