diff --git a/wsme/rest/json.py b/wsme/rest/json.py
index 898c5a0..5aa0ed5 100644
--- a/wsme/rest/json.py
+++ b/wsme/rest/json.py
@@ -11,6 +11,7 @@ from simplegeneric import generic
from wsme.types import Unset
import wsme.types
+from wsme.exc import UnknownArgument
try:
import simplejson as json
@@ -191,68 +192,6 @@ def datetime_fromjson(datatype, value):
return datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S')
-class RestJson(object):
- """
- REST+Json protocol.
-
- .. autoattribute:: name
- .. autoattribute:: dataformat
- .. autoattribute:: content_types
- """
-
- name = 'json'
- content_type = 'application/json'
-
- #def __init__(self, nest_result=False):
- # super(RestJsonProtocol, self).__init__()
- # self.nest_result = nest_result
-
- def decode_arg(self, value, arg):
- return fromjson(arg.datatype, value)
-
- def parse_arg(self, name, value):
- return json.loads(value)
-
- def parse_args(self, body):
- raw_args = json.loads(body)
- return raw_args
-
- def encode_result(self, context, result):
- r = tojson(context.funcdef.return_type, result)
- if self.nest_result:
- r = {'result': r}
- return json.dumps(r)
-
- def encode_sample_value(self, datatype, value, format=False):
- r = tojson(datatype, value)
- content = json.dumps(r, ensure_ascii=False,
- indent=4 if format else 0,
- sort_keys=format)
- return ('javascript', content)
-
- def encode_sample_params(self, params, format=False):
- kw = {}
- for name, datatype, value in params:
- kw[name] = tojson(datatype, value)
- content = json.dumps(kw, ensure_ascii=False,
- indent=4 if format else 0,
- sort_keys=format)
- return ('javascript', content)
-
- def encode_sample_result(self, datatype, value, format=False):
- r = tojson(datatype, value)
- if self.nest_result:
- r = {'result': r}
- content = json.dumps(r, ensure_ascii=False,
- indent=4 if format else 0,
- sort_keys=format)
- return ('javascript', content)
-
-
-def get_format():
- return RestJson()
-
-
def parse(s, datatypes, bodyarg):
if hasattr(s, 'read'):
jdata = json.load(s)
@@ -263,18 +202,47 @@ def parse(s, datatypes, bodyarg):
kw = {argname: fromjson(datatypes[argname], jdata)}
else:
kw = {}
- for key, datatype in datatypes.items():
- if key in jdata:
- kw[key] = fromjson(datatype, jdata[key])
+ for key in jdata:
+ if key not in datatypes:
+ raise UnknownArgument(key)
+ kw[key] = fromjson(datatypes[key], jdata[key])
return kw
-def tostring(value, datatype, attrname=None):
+def encode_result(value, datatype, **options):
jsondata = tojson(datatype, value)
- if attrname is not None:
- jsondata = {attrname: jsondata}
- return json.dumps(tojson(datatype, value))
+ if options.get('nest_result', False):
+ jsondata = {options.get('nested_result_attrname', 'result'): jsondata}
+ return json.dumps(jsondata)
def encode_error(context, errordetail):
return json.dumps(errordetail)
+
+
+def encode_sample_value(datatype, value, format=False):
+ r = tojson(datatype, value)
+ content = json.dumps(r, ensure_ascii=False,
+ indent=4 if format else 0,
+ sort_keys=format)
+ return ('javascript', content)
+
+
+def encode_sample_params(params, format=False):
+ kw = {}
+ for name, datatype, value in params:
+ kw[name] = tojson(datatype, value)
+ content = json.dumps(kw, ensure_ascii=False,
+ indent=4 if format else 0,
+ sort_keys=format)
+ return ('javascript', content)
+
+
+def encode_sample_result(datatype, value, format=False):
+ r = tojson(datatype, value)
+ #if self.nest_result:
+ #r = {'result': r}
+ content = json.dumps(r, ensure_ascii=False,
+ indent=4 if format else 0,
+ sort_keys=format)
+ return ('javascript', content)
diff --git a/wsme/rest/protocol.py b/wsme/rest/protocol.py
index 2fe6c39..769dda9 100644
--- a/wsme/rest/protocol.py
+++ b/wsme/rest/protocol.py
@@ -60,6 +60,9 @@ class RestProtocol(Protocol):
outformat = df
context.outformat = outformat
+ context.outformat_options = {
+ 'nest_result': getattr(self, 'nest_result', False)
+ }
yield context
def extract_path(self, context):
@@ -150,8 +153,9 @@ class RestProtocol(Protocol):
return kw
def encode_result(self, context, result):
- out = context.outformat.tostring(
- result, context.funcdef.return_type
+ out = context.outformat.encode_result(
+ result, context.funcdef.return_type,
+ **context.outformat_options
)
return out
diff --git a/wsme/rest/xml.py b/wsme/rest/xml.py
index 00aa6f2..90f156d 100644
--- a/wsme/rest/xml.py
+++ b/wsme/rest/xml.py
@@ -224,73 +224,6 @@ def datetime_fromxml(datatype, element):
return datetime.datetime.strptime(element.text, '%Y-%m-%dT%H:%M:%S')
-class RestXmlProtocol(RestProtocol):
- """
- REST+XML protocol.
-
- .. autoattribute:: name
- .. autoattribute:: dataformat
- .. autoattribute:: content_types
- """
- name = 'restxml'
- displayname = 'REST+Xml'
- dataformat = 'xml'
- content_types = ['text/xml']
-
- def decode_arg(self, value, arg):
- return fromxml(arg.datatype, value)
-
- def parse_arg(self, name, value):
- return et.fromstring(u("<%s>%s%s>") % (name, value, name))
-
- def parse_args(self, body):
- return dict((sub.tag, sub) for sub in et.fromstring(body))
-
- def encode_result(self, context, result):
- return et.tostring(
- toxml(context.funcdef.return_type, 'result', result))
-
-
-class RestXml(object):
- name = 'xml'
- content_type = 'text/xml'
-
- def encode_error(self, context, errordetail):
- el = et.Element('error')
- et.SubElement(el, 'faultcode').text = errordetail['faultcode']
- et.SubElement(el, 'faultstring').text = errordetail['faultstring']
- if 'debuginfo' in errordetail:
- et.SubElement(el, 'debuginfo').text = errordetail['debuginfo']
- return et.tostring(el)
-
- def encode_sample_value(self, datatype, value, format=False):
- r = toxml(datatype, 'value', value)
- if format:
- xml_indent(r)
- content = et.tostring(r)
- return ('xml', content)
-
- def encode_sample_params(self, params, format=False):
- node = et.Element('parameters')
- for name, datatype, value in params:
- node.append(toxml(datatype, name, value))
- if format:
- xml_indent(node)
- content = et.tostring(node)
- return ('xml', content)
-
- def encode_sample_result(self, datatype, value, format=False):
- r = toxml(datatype, 'result', value)
- if format:
- xml_indent(r)
- content = et.tostring(r)
- return ('xml', content)
-
-
-def get_format():
- return RestXml()
-
-
def parse(s, datatypes, bodyarg):
if hasattr(s, 'read'):
tree = et.parse(s)
@@ -308,8 +241,10 @@ def parse(s, datatypes, bodyarg):
return kw
-def tostring(value, datatype, attrname='result'):
- return et.tostring(toxml(datatype, attrname, value))
+def encode_result(value, datatype, **options):
+ return et.tostring(toxml(
+ datatype, options.get('nested_result_attrname', 'result'), value
+ ))
def encode_error(context, errordetail):
@@ -319,3 +254,29 @@ def encode_error(context, errordetail):
if 'debuginfo' in errordetail:
et.SubElement(el, 'debuginfo').text = errordetail['debuginfo']
return et.tostring(el)
+
+
+def encode_sample_value(datatype, value, format=False):
+ r = toxml(datatype, 'value', value)
+ if format:
+ xml_indent(r)
+ content = et.tostring(r)
+ return ('xml', content)
+
+
+def encode_sample_params(params, format=False):
+ node = et.Element('parameters')
+ for name, datatype, value in params:
+ node.append(toxml(datatype, name, value))
+ if format:
+ xml_indent(node)
+ content = et.tostring(node)
+ return ('xml', content)
+
+
+def encode_sample_result(datatype, value, format=False):
+ r = toxml(datatype, 'result', value)
+ if format:
+ xml_indent(r)
+ content = et.tostring(r)
+ return ('xml', content)
diff --git a/wsme/tests/test_restjson.py b/wsme/tests/test_restjson.py
index b18bf41..90d7712 100644
--- a/wsme/tests/test_restjson.py
+++ b/wsme/tests/test_restjson.py
@@ -263,9 +263,6 @@ class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
[int], {int: int}):
assert fromjson(dt, None) is None
- def test_parse_arg(self):
- assert self.root.protocols[0].parse_arg('a', '5') == 5
-
def test_nest_result(self):
self.root.protocols[0].nest_result = True
r = self.app.get('/returntypes/getint.json')
@@ -283,7 +280,7 @@ class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
v.aint = 4
v.astr = 's'
- r = self.root.protocols[0].encode_sample_value(MyType, v, True)
+ r = wsme.rest.json.encode_sample_value(MyType, v, True)
print(r)
assert r[0] == ('javascript')
assert r[1] == json.dumps({'aint': 4, 'astr': 's'},
@@ -294,7 +291,7 @@ class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
assert tojson(wsme.types.bytes, b('ascii')) == u('ascii')
def test_encode_sample_params(self):
- r = self.root.protocols[0].encode_sample_params(
+ r = wsme.rest.json.encode_sample_params(
[('a', int, 2)], True
)
assert r[0] == 'javascript', r[0]
@@ -303,19 +300,19 @@ class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
}''', r[1]
def test_encode_sample_result(self):
- r = self.root.protocols[0].encode_sample_result(
+ r = wsme.rest.json.encode_sample_result(
int, 2, True
)
assert r[0] == 'javascript', r[0]
assert r[1] == '''2'''
- self.root.protocols[0].nest_result = True
- r = self.root.protocols[0].encode_sample_result(
- int, 2, True
- )
- assert r[0] == 'javascript', r[0]
- assert r[1] == '''{
- "result": 2
-}'''
+ #self.root.protocols[0].nest_result = True
+ #r = wsme.rest.json.encode_sample_result(
+ #int, 2, True
+ #)
+ #assert r[0] == 'javascript', r[0]
+ #assert r[1] == '''{
+ #"result": 2
+#}'''
def test_PUT(self):
data = {"id": 1, "name": u("test")}
diff --git a/wsme/tests/test_restxml.py b/wsme/tests/test_restxml.py
index 8af8150..982df7f 100644
--- a/wsme/tests/test_restxml.py
+++ b/wsme/tests/test_restxml.py
@@ -139,7 +139,7 @@ class TestRestXML(wsme.tests.protocol.ProtocolTestCase):
value.aint = 5
value.atext = u('test')
- language, sample = self.root.protocols[0].encode_sample_value(
+ language, sample = wsme.rest.xml.encode_sample_value(
MyType, value, True)
print (language, sample)
@@ -150,13 +150,13 @@ class TestRestXML(wsme.tests.protocol.ProtocolTestCase):
""")
def test_encode_sample_params(self):
- lang, content = self.root.protocols[0].encode_sample_params(
+ lang, content = wsme.rest.xml.encode_sample_params(
[('a', int, 2)], True)
assert lang == 'xml', lang
assert content == b('\n 2\n'), content
def test_encode_sample_result(self):
- lang, content = self.root.protocols[0].encode_sample_result(int, 2, True)
+ lang, content = wsme.rest.xml.encode_sample_result(int, 2, True)
assert lang == 'xml', lang
assert content == b('2'), content
@@ -183,8 +183,3 @@ class TestRestXML(wsme.tests.protocol.ProtocolTestCase):
x = et.tostring(toxml(AType, 'value', AType()))
assert x == b(''), x
-
- def test_parse_arg(self):
- e = self.root.protocols[0].parse_arg('value', '5')
- assert e.text == '5'
- assert e.tag == 'value'