Based on this answer, I was able to create and deploy 2 web services. However, if one service tried to call another, it hanged there until timeout.
My code is:
from wsgiref.simple_server import make_server
from spyne.application import Application
from spyne.protocol.soap import Soap11
from spyne.util.wsgi_wrapper import WsgiMounter
from suds.client import Client
from spyne.decorator import srpc
from spyne.service import ServiceBase
from spyne.model.primitive import Unicode
class Service_Caller(ServiceBase):
@srpc(_returns=Unicode)
def call_service():
client = Client("http://localhost:8000/hello?wsdl")
result = client.service.say_hello('world')
return result
class HelloWorldService(ServiceBase):
@srpc(Unicode, _returns=Unicode)
def say_hello(name):
return [u'Hello, %s' % name]
if __name__ == '__main__':
app1 = Application([Service_Caller], 'example1',
in_protocol=Soap11(), out_protocol=Soap11())
app2 = Application([HelloWorldService], 'example2',
in_protocol=Soap11(), out_protocol=Soap11())
wsgi_app = WsgiMounter({"caller":app1, "hello":app2})
server = make_server('0.0.0.0', 8000, wsgi_app)
server.serve_forever()
Service is called using:
from suds.client import Client
client = Client('http://localhost:8000/caller?wsdl')
client.service.call_service()
At the moment, the only way for my code to work is to deploy 2 services on different domain or on different port. I wonder if anyone has the same problem and knows any workaround. Thanks.
That's because of the WSGI implementation that you're using(wsgiref
). wsgiref
is just a reference Wsgi implementation and does not support concurrency. For production use, you should switch to a proper wsgi container like mod_wsgi, CherryPy, twisted, etc and never use wsgiref
.
Again, and I can't stress this enough, never use wsgiref
for production use.
That being said, if you just want to call one service from another one, there's a better way:
from spyne.util.appreg import get_application
app = get_application('example2', 'Application').null
print app.service.say_hello('world')
Here's the fully working example:
from spyne.application import Application
from spyne.protocol.soap import Soap11
from spyne.util.wsgi_wrapper import WsgiMounter
from spyne.decorator import srpc
from spyne.service import ServiceBase
from spyne.model.primitive import Unicode
from spyne.util.appreg import get_application
class Service_Caller(ServiceBase):
@srpc(_returns=Unicode)
def call_service():
# 'Application' is the default when you omit the `name` argument to the
# `Application` initializer.
app1 = get_application('example2', 'Application').null
result = '\n'.join(app1.service.say_hello('world'))
return result
class HelloWorldService(ServiceBase):
@srpc(Unicode, _returns=Unicode)
def say_hello(name):
return [u'Hello, %s' % name]
if __name__ == '__main__':
import logging
logging.basicConfig(level=logging.DEBUG)
app1 = Application([Service_Caller], 'example1',
in_protocol=Soap11(), out_protocol=Soap11())
app2 = Application([HelloWorldService], 'example2',
in_protocol=Soap11(), out_protocol=Soap11())
wsgi_app = WsgiMounter({"caller":app1, "hello":app2})
from wsgiref.simple_server import make_server
server = make_server('0.0.0.0', 8000, wsgi_app)
server.serve_forever()
I hope that helps.