Start working on the soap protocol
This commit is contained in:
parent
732626c176
commit
5ca78e896f
@ -14,3 +14,8 @@ syntax: regexp
|
||||
^include
|
||||
^dist
|
||||
|
||||
^examples/.*/bin
|
||||
^examples/.*/dist
|
||||
^examples/.*/lib
|
||||
^examples/.*/include
|
||||
|
||||
|
@ -16,6 +16,7 @@ from wsme import *
|
||||
|
||||
import wsme.restjson
|
||||
import wsme.restxml
|
||||
import wsme.soap
|
||||
|
||||
|
||||
class DemoRoot(WSRoot):
|
||||
|
2
examples/demo/setup.cfg
Normal file
2
examples/demo/setup.cfg
Normal file
@ -0,0 +1,2 @@
|
||||
[easy_install]
|
||||
find_links = http://www.owlfish.com/software/wsgiutils/download.html
|
@ -6,5 +6,6 @@ setup(name='demo',
|
||||
'PasteScript',
|
||||
'PasteDeploy',
|
||||
'WSGIUtils',
|
||||
'Pygments',
|
||||
],
|
||||
package=['demo'])
|
||||
|
@ -54,6 +54,8 @@ class FunctionDefinition(object):
|
||||
self.name = func.__name__
|
||||
self.return_type = None
|
||||
self.arguments = []
|
||||
self.protocol_specific = False
|
||||
self.contenttype = None
|
||||
|
||||
@classmethod
|
||||
def get(cls, func):
|
||||
@ -80,6 +82,19 @@ class expose(object):
|
||||
return func
|
||||
|
||||
|
||||
class pexpose(object):
|
||||
def __init__(self, return_type=None, contenttype=None):
|
||||
self.return_type = return_type
|
||||
self.contenttype = contenttype
|
||||
register_type(return_type)
|
||||
|
||||
def __call__(self, func):
|
||||
fd = FunctionDefinition.get(func)
|
||||
fd.return_type = self.return_type
|
||||
fd.protocol_specific = True
|
||||
fd.contenttype = self.contenttype
|
||||
return func
|
||||
|
||||
class validate(object):
|
||||
def __init__(self, *args, **kw):
|
||||
self.param_types = args
|
||||
@ -124,40 +139,47 @@ class WSRoot(object):
|
||||
|
||||
def _handle_request(self, request):
|
||||
res = webob.Response()
|
||||
res_content_type = None
|
||||
try:
|
||||
protocol = self._select_protocol(request)
|
||||
if protocol is None:
|
||||
msg = ("None of the following protocols can handle this "
|
||||
"request : %s" % ','.join(self.protocols.keys()))
|
||||
"request : %s" % ','.join(self.protocols.keys()))
|
||||
res.status = 500
|
||||
res.text = msg
|
||||
log.error(msg)
|
||||
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 and funcdef.arguments or None)
|
||||
|
||||
result = func(**kw)
|
||||
|
||||
# TODO make sure result type == a._wsme_definition.return_type
|
||||
res.status = 200
|
||||
res.body = protocol.encode_result(result, funcdef.return_type)
|
||||
|
||||
if funcdef.protocol_specific and funcdef.return_type is None:
|
||||
res.body = result
|
||||
else:
|
||||
# TODO make sure result type == a._wsme_definition.return_type
|
||||
res.body = protocol.encode_result(result, funcdef.return_type)
|
||||
res_content_type = funcdef.contenttype
|
||||
except Exception, e:
|
||||
infos = self._format_exception(sys.exc_info())
|
||||
log.error(str(infos))
|
||||
res.status = 500
|
||||
res.body = protocol.encode_error(
|
||||
self._format_exception(sys.exc_info()))
|
||||
res.body = protocol.encode_error(infos)
|
||||
|
||||
# Attempt to correctly guess what content-type we should return.
|
||||
res_content_type = None
|
||||
|
||||
last_q = 0
|
||||
if hasattr(request.accept, '_parsed'):
|
||||
for mimetype, q in request.accept._parsed:
|
||||
if mimetype in protocol.content_types and last_q < q:
|
||||
res_content_type = mimetype
|
||||
else:
|
||||
res_content_type = request.accept.best_match([
|
||||
ct for ct in protocol.content_types if ct])
|
||||
if res_content_type is None:
|
||||
# Attempt to correctly guess what content-type we should return.
|
||||
last_q = 0
|
||||
if hasattr(request.accept, '_parsed'):
|
||||
for mimetype, q in request.accept._parsed:
|
||||
if mimetype in protocol.content_types and last_q < q:
|
||||
res_content_type = mimetype
|
||||
else:
|
||||
res_content_type = request.accept.best_match([
|
||||
ct for ct in protocol.content_types if ct])
|
||||
|
||||
# If not we will attempt to convert the body to an accepted
|
||||
# output format.
|
||||
@ -175,15 +197,27 @@ class WSRoot(object):
|
||||
def _lookup_function(self, path):
|
||||
a = self
|
||||
|
||||
isprotocol_specific = path[0] == '_protocol'
|
||||
|
||||
if isprotocol_specific:
|
||||
a = self.protocols[path[1]]
|
||||
path = path[2:]
|
||||
|
||||
print path, a, a.api_wsdl
|
||||
|
||||
for name in path:
|
||||
a = getattr(a, name, None)
|
||||
if a is None:
|
||||
break
|
||||
|
||||
print a
|
||||
|
||||
if not hasattr(a, '_wsme_definition'):
|
||||
raise exc.UnknownFunction('/'.join(path))
|
||||
|
||||
return a, a._wsme_definition
|
||||
definition = a._wsme_definition
|
||||
|
||||
return a, definition
|
||||
|
||||
def _format_exception(self, excinfo):
|
||||
"""Extract informations that can be sent to the client."""
|
||||
|
58
wsme/soap.py
58
wsme/soap.py
@ -1,9 +1,63 @@
|
||||
from wsme.controller import register_protocol, pexpose
|
||||
|
||||
from xml.etree import ElementTree as et
|
||||
|
||||
|
||||
|
||||
class SoapProtocol(object):
|
||||
name = 'soap'
|
||||
accept = ''
|
||||
content_types = ['application/soap+xml']
|
||||
|
||||
ns = {
|
||||
"soap": "http://www.w3.org/2001/12/soap-envelope"
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def accept(self, root, req):
|
||||
if req.headers['Content-Type'] in self.content_types:
|
||||
return True
|
||||
if req.path.endswith('.wsdl'):
|
||||
return True
|
||||
return False
|
||||
|
||||
controller.register_protocol(SoapProtocol)
|
||||
def extract_path(self, request):
|
||||
if request.path.endswith('.wsdl'):
|
||||
print "Here !!"
|
||||
return ['_protocol', 'soap', 'api_wsdl']
|
||||
|
||||
def read_arguments(self, request, arguments):
|
||||
if arguments is None:
|
||||
return {}
|
||||
return {}
|
||||
|
||||
def encode_result(self, result, return_type):
|
||||
return ""
|
||||
|
||||
def make_header(self):
|
||||
header = et.Element('{%(soap)s}Header' % self.ns)
|
||||
return header
|
||||
|
||||
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 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)
|
||||
|
||||
@pexpose(contenttype="text/xml")
|
||||
def api_wsdl(self):
|
||||
return """<wsdl/>"""
|
||||
|
||||
|
||||
register_protocol(SoapProtocol)
|
||||
|
Loading…
Reference in New Issue
Block a user