diff --git a/wsme/controller.py b/wsme/controller.py
index 3f63158..e53f34a 100644
--- a/wsme/controller.py
+++ b/wsme/controller.py
@@ -36,9 +36,11 @@ def scan_api(controller, path=[]):
a = getattr(controller, name)
if inspect.ismethod(a):
if hasattr(a, '_wsme_definition'):
- yield path, a._wsme_definition
+ a._wsme_definition.path = path
+ yield a._wsme_definition
else:
- if len(path) > 10: raise ValueError(str(path))
+ if len(path) > 10:
+ raise ValueError(str(path))
for i in scan_api(a, path + [name]):
yield i
@@ -59,6 +61,7 @@ class FunctionDefinition(object):
self.arguments = []
self.protocol_specific = False
self.contenttype = None
+ self.path = None
@classmethod
def get(cls, func):
@@ -98,6 +101,7 @@ class pexpose(object):
fd.contenttype = self.contenttype
return func
+
class validate(object):
def __init__(self, *args, **kw):
self.param_types = args
@@ -129,6 +133,13 @@ class WSRoot(object):
protocol = registered_protocols[protocol]()
self.protocols[protocol.name] = protocol
+ self._api = None
+
+ def getapi(self):
+ if self._api is None:
+ self._api = [i for i in scan_api(self)]
+ return self._api
+
def _select_protocol(self, request):
protocol = None
if 'wsmeproto' in request.params:
@@ -154,7 +165,7 @@ class WSRoot(object):
return res
path = protocol.extract_path(request)
func, funcdef = self._lookup_function(path)
- kw = protocol.read_arguments(request, funcdef.arguments)
+ kw = protocol.read_arguments(request, funcdef)
if funcdef.protocol_specific:
kw['root'] = self
@@ -167,7 +178,7 @@ class WSRoot(object):
res.body = result
else:
# TODO make sure result type == a._wsme_definition.return_type
- res.body = protocol.encode_result(result, funcdef.return_type)
+ res.body = protocol.encode_result(result, funcdef)
res_content_type = funcdef.contenttype
except Exception, e:
infos = self._format_exception(sys.exc_info())
@@ -203,7 +214,7 @@ class WSRoot(object):
a = self
isprotocol_specific = path[0] == '_protocol'
-
+
if isprotocol_specific:
a = self.protocols[path[1]]
path = path[2:]
diff --git a/wsme/soap.py b/wsme/soap.py
index fc5ab91..b8e6660 100644
--- a/wsme/soap.py
+++ b/wsme/soap.py
@@ -2,7 +2,7 @@ import pkg_resources
from xml.etree import ElementTree as et
from genshi.template import MarkupTemplate
-from wsme.controller import register_protocol, pexpose, scan_api
+from wsme.controller import register_protocol, pexpose
import wsme.types
nativetypes = {
@@ -29,64 +29,62 @@ class SoapProtocol(object):
def accept(self, root, req):
if req.path.endswith('.wsdl'):
return True
- if req.headers['Content-Type'] in self.content_types:
- return True
+ for ct in self.content_types:
+ if req.headers['Content-Type'].startswith(ct):
+ return True
return False
def extract_path(self, request):
if request.path.endswith('.wsdl'):
print "Here !!"
return ['_protocol', self.name, 'api_wsdl']
+ el = et.fromstring(request.body)
+ body = el.find('{http://schemas.xmlsoap.org/soap/envelope/}Body')
+ fname = list(body)[0].tag
+ print fname
+ return [fname]
- def read_arguments(self, request, arguments):
- if arguments is None:
- return {}
+ def read_arguments(self, request, funcdef):
return {}
- def encode_result(self, result, return_type):
- return ""
+ def encode_result(self, result, funcdef):
+ envelope = self.render_template('soap')
+ print envelope
+ return envelope
- def make_header(self):
- header = et.Element('{%(soap)s}Header' % self.ns)
- return header
+ def get_template(self, name):
+ return pkg_resources.resource_string(
+ __name__, 'templates/%s.html' % name)
- def make_body(self):
- body = et.Element('{%(soap)s}Body' % self.ns)
- return body
-
- def make_envelope(self):
- env = et.Element('{%(soap)s}Envelope' % self.ns)
- env.append(self.make_header())
- env.append(self.make_body())
- return env
+ def render_template(self, name, **kw):
+ tmpl = MarkupTemplate(self.get_template(name))
+ stream = tmpl.generate(**kw)
+ return stream.render('xml')
def encode_error(self, infos):
- env = self.make_envelope()
- fault = et.Element('{%(soap)s}Fault' % self.ns)
- env.find('{%(soap)s}Body' % self.ns).append(fault)
- return et.tostring(env)
-
+ return self.render_template('fault',
+ typenamespace=self.typenamespace,
+ **infos)
+
@pexpose(contenttype="text/xml")
def api_wsdl(self, root, service=None):
if service is None:
servicename = self.servicename
else:
servicename = self.servicename + service.capitalize()
- tmpl = MarkupTemplate(
- pkg_resources.resource_string(__name__, 'templates/wsdl.html'))
- stream = tmpl.generate(
+ return self.render_template('wsdl',
tns = self.tns,
typenamespace = self.typenamespace,
soapenc = 'http://schemas.xmlsoap.org/soap/encoding/',
service_name = servicename,
complex_types = (t() for t in wsme.types.complex_types),
- funclist = [i for i in scan_api(root)],
+ funclist = root.getapi(),
arrays = [],
list_attributes = wsme.types.list_attributes,
baseURL = service,
soap_type = self.soap_type,
- )
- return stream.render('xml')
+ soap_fname = self.soap_fname,
+ )
def soap_type(self, datatype):
if datatype in nativetypes:
@@ -94,4 +92,9 @@ class SoapProtocol(object):
if wsme.types.iscomplex(datatype):
return "types:%s" % datatype.__name__
+ def soap_fname(self, funcdef):
+ return "%s%s" % (
+ "".join((i.capitalize() for i in funcdef.path)),
+ funcdef.name.capitalize())
+
register_protocol(SoapProtocol)
diff --git a/wsme/templates/fault.html b/wsme/templates/fault.html
new file mode 100644
index 0000000..62084ea
--- /dev/null
+++ b/wsme/templates/fault.html
@@ -0,0 +1,14 @@
+
+
+
+ ${faultcode}
+ ${faultstring}
+ ${debuginfo}
+
+
+
diff --git a/wsme/templates/soap.html b/wsme/templates/soap.html
new file mode 100644
index 0000000..d4114ed
--- /dev/null
+++ b/wsme/templates/soap.html
@@ -0,0 +1,10 @@
+
+
+ ${soap_body(methodname, function_info, output)}
+
+
diff --git a/wsme/templates/wsdl.html b/wsme/templates/wsdl.html
index 8bbd957..289d2a7 100644
--- a/wsme/templates/wsdl.html
+++ b/wsme/templates/wsdl.html
@@ -22,8 +22,8 @@
-
-
+
+
-
+
-
-
-
+
+
+
-
-
+
+
-
+
${funcdef.doc}
-
-
+
+
@@ -79,8 +79,8 @@
-
-
+
+
diff --git a/wsme/tests/test_soap.py b/wsme/tests/test_soap.py
index a4ebc43..6204c16 100644
--- a/wsme/tests/test_soap.py
+++ b/wsme/tests/test_soap.py
@@ -11,6 +11,24 @@ except:
import wsme.soap
+def build_soap_message(method, params=""):
+ message = """
+
+
+
+ <%(method)s>
+ %(params)s
+ %(method)s>
+
+
+
+""" % dict(method=method, params=params)
+ return message
+
+
def dumpxml(key, obj):
el = et.Element(key)
if isinstance(obj, basestring):
@@ -38,7 +56,19 @@ def loadxml(el):
class TestSOAP(wsme.tests.protocol.ProtocolTestCase):
protocol = 'SOAP'
+ def test_simple_call(self):
+ message = build_soap_message('Touch')
+ print message
+ res = self.app.post('/', message,
+ headers={
+ "Content-Type": "application/soap+xml; charset=utf-8"
+ }, expect_errors=True)
+ print res.body
+ assert res.status.startswith('200')
+
def call(self, fpath, **kw):
+ # get the actual definition so we can build the adequate request
+
el = dumpxml('parameters', kw)
content = et.tostring(el)
res = self.app.post(
@@ -63,5 +93,4 @@ class TestSOAP(wsme.tests.protocol.ProtocolTestCase):
def test_wsdl(self):
res = self.app.get('/api.wsdl')
print res.body
- assert 'returntypes' in res.body
- assert False
+ assert 'ReturntypesGetunicode' in res.body