From bcf76e7075858a69e4dfb2ff8d68f1247ed125fc Mon Sep 17 00:00:00 2001 From: Christophe de Vienne Date: Thu, 29 Mar 2012 18:30:50 +0200 Subject: [PATCH] Introduce a Protocol base class, and add a method to render a sample data (used by the documentation tool) --- wsme/protocols/__init__.py | 27 +++++++++++++++++++++++++++ wsme/protocols/rest.py | 13 ++----------- wsme/protocols/restjson.py | 8 ++++++++ wsme/protocols/restxml.py | 24 ++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/wsme/protocols/__init__.py b/wsme/protocols/__init__.py index 137d142..1c86bec 100644 --- a/wsme/protocols/__init__.py +++ b/wsme/protocols/__init__.py @@ -24,6 +24,33 @@ class CallContext(object): return self._request() +class Protocol(object): + name = None + displayname = None + dataformat = None + content_types = [] + + def accept(self, request): + if request.path.endswith('.' + self.dataformat): + return True + return request.headers.get('Content-Type') in self.content_types + + def iter_calls(self, request): + pass + + def extract_path(self, context): + pass + + def read_arguments(self, context): + pass + + def encode_result(self, context, result): + pass + + def encode_sample_value(self, datatype, value, format=False): + return ('none', 'N/A') + + def register_protocol(protocol): registered_protocols[protocol.name] = protocol diff --git a/wsme/protocols/rest.py b/wsme/protocols/rest.py index dca7352..cf1ac7a 100644 --- a/wsme/protocols/rest.py +++ b/wsme/protocols/rest.py @@ -1,23 +1,14 @@ import logging from wsme.exc import ClientSideError, UnknownArgument -from wsme.protocols import CallContext +from wsme.protocols import CallContext, Protocol from wsme.protocols.commons import from_params from wsme.types import Unset log = logging.getLogger(__name__) -class RestProtocol(object): - name = None - dataformat = None - content_types = [] - - def accept(self, request): - if request.path.endswith('.' + self.dataformat): - return True - return request.headers.get('Content-Type') in self.content_types - +class RestProtocol(Protocol): def iter_calls(self, request): yield CallContext(request) diff --git a/wsme/protocols/restjson.py b/wsme/protocols/restjson.py index a47ccca..d93d6ae 100644 --- a/wsme/protocols/restjson.py +++ b/wsme/protocols/restjson.py @@ -186,6 +186,7 @@ class RestJsonProtocol(RestProtocol): """ name = 'restjson' + displayname = 'REST+Json' dataformat = 'json' content_types = [ 'application/json', @@ -215,3 +216,10 @@ class RestJsonProtocol(RestProtocol): def encode_error(self, context, errordetail): return json.dumps(errordetail, encoding='utf-8') + + 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) diff --git a/wsme/protocols/restxml.py b/wsme/protocols/restxml.py index 2e90875..456b5af 100644 --- a/wsme/protocols/restxml.py +++ b/wsme/protocols/restxml.py @@ -15,6 +15,20 @@ import re time_re = re.compile(r'(?P[0-2][0-9]):(?P[0-5][0-9]):(?P[0-6][0-9])') +def xml_indent(elem, level=0): + i = "\n" + level * " " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + for e in elem: + xml_indent(e, level + 1) + if not e.tail or not e.tail.strip(): + e.tail = i + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i + + + @generic def toxml(datatype, key, value): """ @@ -193,6 +207,7 @@ class RestXmlProtocol(RestProtocol): .. autoattribute:: content_types """ name = 'restxml' + displayname = 'REST+Xml' dataformat = 'xml' content_types = ['text/xml'] @@ -216,3 +231,12 @@ class RestXmlProtocol(RestProtocol): 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) + #indent=4 if format else 0, + #sort_keys=format) + return ('xml', content)