summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--result_collection_api/tornado_swagger_ui/README.md52
-rw-r--r--result_collection_api/tornado_swagger_ui/example/basic.py16
-rw-r--r--result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py71
3 files changed, 116 insertions, 23 deletions
diff --git a/result_collection_api/tornado_swagger_ui/README.md b/result_collection_api/tornado_swagger_ui/README.md
index 1ae3834..707eec0 100644
--- a/result_collection_api/tornado_swagger_ui/README.md
+++ b/result_collection_api/tornado_swagger_ui/README.md
@@ -28,9 +28,9 @@ class ItemNoParamHandler(GenericApiHandler):
@swagger.operation(nickname='create')
def post(self):
"""
- @param body: create test results for a pod.
+ @param body: create test results for a item.
@type body: L{Item}
- @return 200: pod is created.
+ @return 200: item is created.
@raise 400: invalid input
"""
@@ -49,9 +49,9 @@ class ItemNoParamHandler(GenericApiHandler):
def make_app():
return swagger.Application([
- (r"/pods", ItemNoParamHandler),
- (r"/pods/([^/]+)", ItemHandler),
- (r"/projects/([^/]+)/cases/([^/]+)", ItemOptionParamHandler),
+ (r"/items", ItemNoParamHandler),
+ (r"/items/([^/]+)", ItemHandler),
+ (r"/items/([^/]+)/cases/([^/]+)", ItemOptionParamHandler),
])
# You define models like this:
@@ -157,6 +157,48 @@ class Item:
]
}
}
+
+# if you want to declare an list property, you can do it like this:
+class Item:
+ """
+ @ptype property3: L{PropertySubclass}
+ @ptype property4: C{list} of L{PropertySubclass}
+ """
+ def __init__(self, property1, property2, property3, property4=None):
+ self.property1 = property1
+ self.property2 = property2
+ self.property3 = property3
+ self.property4 = property4
+
+# Swagger json:
+ "models": {
+ "Item": {
+ "description": "A description...",
+ "id": "Item",
+ "required": [
+ "property1",
+ ],
+ "properties": [
+ "property1": {
+ "type": "string"
+ },
+ "property2": {
+ "type": "string"
+ },
+ "property3": {
+ "type": "PropertySubclass"
+ "default": null
+ },
+ "property4": {
+ "default": null,
+ "items": {
+ "type": "PropertySubclass"},
+ "type": "array"
+ }
+ }
+ ]
+ }
+ }
```
# Running and testing
diff --git a/result_collection_api/tornado_swagger_ui/example/basic.py b/result_collection_api/tornado_swagger_ui/example/basic.py
index ded99d5..20ad9cb 100644
--- a/result_collection_api/tornado_swagger_ui/example/basic.py
+++ b/result_collection_api/tornado_swagger_ui/example/basic.py
@@ -28,11 +28,13 @@ class Item:
In this case we would have property1, name as required parameters and property3 as optional parameter.
@property property3: Item description
@ptype property3: L{PropertySubclass}
+ @ptype property4: C{list} of L{PropertySubclass}
"""
- def __init__(self, property1, property2=None, property3=None):
+ def __init__(self, property1, property2=None, property3=None, property4=None):
self.property1 = property1
self.property2 = property2
self.property3 = property3
+ self.property4 = property4
items = {}
@@ -71,9 +73,9 @@ class ItemNoParamHandler(GenericApiHandler):
@swagger.operation(nickname='create')
def post(self):
"""
- @param body: create test results for a pod.
+ @param body: create a item.
@type body: L{Item}
- @return 200: pod is created.
+ @return 200: item is created.
@raise 400: invalid input
"""
property1 = self.json_args.get('property1')
@@ -99,9 +101,9 @@ class ItemHandler(GenericApiHandler):
def get(self, arg):
"""
@rtype: L{Item}
- @description: get pod's test results
+ @description: get information of a item
@notes:
- get a pod test results,
+ get a item,
This will be added to the Implementation Notes.It lets you put very long text in your api.
"""
@@ -110,9 +112,9 @@ class ItemHandler(GenericApiHandler):
@swagger.operation(nickname='delete')
def delete(self, arg):
"""
- @description: delete pod by pod_id
+ @description: delete a item
@notes:
- delete test results of a pod
+ delete a item in items
This will be added to the Implementation Notes.It lets you put very long text in your api.
"""
diff --git a/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py b/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py
index 2d688a8..0939b0d 100644
--- a/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py
+++ b/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py
@@ -4,6 +4,7 @@
import inspect
from functools import wraps
import epydoc.markup
+from HTMLParser import HTMLParser
import tornado.web
from settings import default_settings, models
from handlers import swagger_handlers
@@ -11,6 +12,30 @@ from handlers import swagger_handlers
__author__ = 'serena'
+class EpytextParser(HTMLParser):
+ a_text = False
+
+ def __init__(self, tag):
+ HTMLParser.__init__(self)
+ self.tag = tag
+ self.data = None
+
+ def handle_starttag(self, tag, attr):
+ if tag == self.tag:
+ self.a_text = True
+
+ def handle_endtag(self, tag):
+ if tag == self.tag:
+ self.a_text = False
+
+ def handle_data(self, data):
+ if self.a_text:
+ self.data = data
+
+ def get_data(self):
+ return self.data
+
+
class DocParser(object):
def __init__(self):
self.notes = None
@@ -31,7 +56,7 @@ class DocParser(object):
for field in fields:
tag = field.tag()
arg = field.arg()
- body = field.body().to_plaintext(None).strip()
+ body = field.body()
self._get_parser(tag)(arg=arg, body=body)
return doc
@@ -51,7 +76,7 @@ class DocParser(object):
def _parse_param(self, **kwargs):
arg = kwargs.get('arg', None)
- body = kwargs.get('body', None)
+ body = self._get_body(**kwargs)
self.params.setdefault(arg, {}).update({
'name': arg,
'description': body,
@@ -65,14 +90,14 @@ class DocParser(object):
def _parse_type(self, **kwargs):
arg = kwargs.get('arg', None)
- body = kwargs.get('body', None)
+ body = self._get_body(**kwargs)
self.params.setdefault(arg, {}).update({
'name': arg,
'dataType': body
})
def _parse_rtype(self, **kwargs):
- body = kwargs.get('body', None)
+ body = self._get_body(**kwargs)
self.responseClass = body
def _parse_property(self, **kwargs):
@@ -83,25 +108,32 @@ class DocParser(object):
def _parse_ptype(self, **kwargs):
arg = kwargs.get('arg', None)
- body = kwargs.get('body', None)
- self.properties.setdefault(arg, {}).update({
- 'type': body
- })
+ code = self._parse_epytext_para('code', **kwargs)
+ link = self._parse_epytext_para('link', **kwargs)
+ if code is None:
+ self.properties.setdefault(arg, {}).update({
+ 'type': link
+ })
+ elif code == 'list':
+ self.properties.setdefault(arg, {}).update({
+ 'type': 'array',
+ 'items': {'type': link}
+ })
def _parse_return(self, **kwargs):
arg = kwargs.get('arg', None)
- body = kwargs.get('body', None)
+ body = self._get_body(**kwargs)
self.responseMessages.append({
'code': arg,
'message': body
})
def _parse_notes(self, **kwargs):
- body = kwargs.get('body', '')
+ body = self._get_body(**kwargs)
self.notes = self._sanitize_doc(body)
def _parse_description(self, **kwargs):
- body = kwargs.get('body', '')
+ body = self._get_body(**kwargs)
self.summary = self._sanitize_doc(body)
def _not_supported(self, **kwargs):
@@ -111,6 +143,23 @@ class DocParser(object):
def _sanitize_doc(comment):
return comment.replace('\n', '<br/>') if comment else comment
+ @staticmethod
+ def _get_body(**kwargs):
+ body = kwargs.get('body', None)
+ return body.to_plaintext(None).strip() if body else body
+
+ @staticmethod
+ def _parse_epytext_para(tag, **kwargs):
+ def _parse_epytext(tag, body):
+ epytextParser = EpytextParser(tag)
+ epytextParser.feed(str(body))
+ data = epytextParser.get_data()
+ epytextParser.close()
+ return data
+
+ body = kwargs.get('body', None)
+ return _parse_epytext(tag, body) if body else body
+
class model(DocParser):
def __init__(self, cls=None, *args, **kwargs):