tornado_swagger_ui support query operation in "GET" method, and support methods in... 77/14077/2
authorSerenaFeng <feng.xiaowei@zte.com.cn>
Fri, 13 May 2016 07:58:04 +0000 (15:58 +0800)
committerSerenaFeng <feng.xiaowei@zte.com.cn>
Fri, 13 May 2016 08:10:08 +0000 (16:10 +0800)
query: GET /item?property1=1&property2=1
methods in model:
    @swagger.model()
    class Item:
        def format_http(self):
            pass
        @staticmethod
        def item_from_dict(item_dict):
            pass
        @classmethod
        def test_classmethod(cls):
            pass

JIRA: FUNCTEST-250

Change-Id: I12f937c4d2f64f93dc1194a8ad982e8b7ff21b7c
Signed-off-by: SerenaFeng <feng.xiaowei@zte.com.cn>
utils/test/result_collection_api/tornado_swagger_ui/README.md
utils/test/result_collection_api/tornado_swagger_ui/__init__.py [new file with mode: 0644]
utils/test/result_collection_api/tornado_swagger_ui/example/basic.py
utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py
utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py
utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py
utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py

index 707eec0..e90e130 100644 (file)
@@ -199,6 +199,59 @@ class Item:
             ]
         }
     }
+
+# if it is a query:
+class ItemQueryHandler(GenericApiHandler):
+    @swagger.operation(nickname='query')
+    def get(self):
+        """
+           @param property1:
+           @type property1: L{string}
+           @in property1: query
+           @required property1: False
+
+           @param property2:
+           @type property2: L{string}
+           @in property2: query
+           @required property2: True
+           @rtype: L{Item}
+
+           @notes: GET /item?property1=1&property2=1
+        """
+
+# Swagger json:
+    "apis": [
+        {
+            "operations": [
+                {
+                    "parameters": [
+                        {
+                            "name": "property1",
+                            "dataType": "string",
+                            "paramType": "query",
+                            "description": ""
+                        },
+                        {
+                            "name": "property2",
+                            "dataType": "string",
+                            "paramType": "query",
+                            "required": true,
+                            "description": ""
+                        }
+                    ],
+                    "responseClass": "Item",
+                    "notes": null,
+                    "responseMessages": [],
+                    "summary": null,
+                    "httpMethod": "GET",
+                    "nickname": "query"
+                }
+            ],
+            "path": "/item",
+            "description": null
+        },
+        ....
+    ]
 ```
 
 # Running and testing
diff --git a/utils/test/result_collection_api/tornado_swagger_ui/__init__.py b/utils/test/result_collection_api/tornado_swagger_ui/__init__.py
new file mode 100644 (file)
index 0000000..49b1b74
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+__author__ = 'serena'
+
index 20ad9cb..1731bfd 100644 (file)
@@ -2,7 +2,7 @@ import json
 
 import tornado.ioloop
 from tornado.web import RequestHandler, HTTPError
-from tornado_swagger import swagger
+from tornado_swagger_ui.tornado_swagger import swagger
 
 DEFAULT_REPRESENTATION = "application/json"
 HTTP_BAD_REQUEST = 400
@@ -12,13 +12,13 @@ HTTP_NOT_FOUND = 404
 swagger.docs()
 
 
-@swagger.model
+@swagger.model()
 class PropertySubclass:
     def __init__(self, sub_property=None):
         self.sub_property = sub_property
 
 
-@swagger.model
+@swagger.model()
 class Item:
     """
         @description:
@@ -36,6 +36,33 @@ class Item:
         self.property3 = property3
         self.property4 = property4
 
+    def format_http(self):
+        return {
+            "property1": self.property1,
+            "property2": self.property2,
+            "property3": self.property3,
+            "property4": self.property4,
+        }
+
+    @staticmethod
+    def item_from_dict(item_dict):
+
+        if item_dict is None:
+            return None
+
+        t = Item(None)
+        t.property1 = item_dict.get('property1')
+        t.property2 = item_dict.get('property2')
+        t.property3 = item_dict.get('property3')
+        t.property4 = item_dict.get('property4')
+
+        return t
+
+    @classmethod
+    def test_classmethod(cls):
+        pass
+
+
 items = {}
 
 
@@ -75,19 +102,25 @@ class ItemNoParamHandler(GenericApiHandler):
         """
             @param body: create a item.
             @type body: L{Item}
+            @in body: body
             @return 200: item is created.
             @raise 400: invalid input
         """
         property1 = self.json_args.get('property1')
-        items[property1] = self.json_args
-        self.finish_request(items[property1])
+        item = Item.item_from_dict(self.json_args)
+        items[property1] = item
+        Item.test_classmethod()
+        self.finish_request(item.format_http())
 
     @swagger.operation(nickname='list')
     def get(self):
         """
            @rtype: L{Item}
         """
-        self.finish_request(items)
+        res = []
+        for key, value in items.iteritems():
+            res.append(value.format_http())
+        self.finish_request(res)
 
     def options(self):
         """
@@ -107,7 +140,7 @@ class ItemHandler(GenericApiHandler):
 
                 This will be added to the Implementation Notes.It lets you put very long text in your api.
         """
-        self.finish_request(items[arg])
+        self.finish_request(items[arg].format_http())
 
     @swagger.operation(nickname='delete')
     def delete(self, arg):
@@ -134,8 +167,42 @@ class ItemOptionParamHandler(GenericApiHandler):
         self.write("success")
 
 
+class ItemQueryHandler(GenericApiHandler):
+    @swagger.operation(nickname='query')
+    def get(self):
+        """
+           @param property1:
+           @type property1: L{string}
+           @in property1: query
+           @required property1: False
+
+           @param property2:
+           @type property2: L{string}
+           @in property2: query
+           @required property2: True
+           @rtype: L{Item}
+           @notes: GET /item?property1=1&property2=1
+        """
+        property1 = self.get_query_argument("property1", None)
+        property2 = self.get_query_argument("property2", None)
+
+        res = []
+        if property1 is None:
+            for key, value in items.iteritems():
+                if property2 is None:
+                    res.append(value.format_http())
+                elif value.property2 == property2:
+                    res.append(value.format_http())
+        elif items.has_key(property1):
+            if items.get(property1).property2 == property2:
+                res.append(items.get(property1).format_http())
+
+        self.finish_request(res)
+
+
 def make_app():
     return swagger.Application([
+        (r"/item", ItemQueryHandler),
         (r"/items", ItemNoParamHandler),
         (r"/items/([^/]+)", ItemHandler),
         (r"/items/([^/]+)/cases/([^/]+)", ItemOptionParamHandler),
index c9d49ae..33c4b53 100644 (file)
@@ -2,8 +2,8 @@
 # -*- coding: utf-8 -*-
 from tornado.web import URLSpec, StaticFileHandler
 
-from tornado_swagger.settings import *
-from tornado_swagger.views import *
+from settings import *
+from views import *
 
 __author__ = 'serena'
 
index 0939b0d..50b2cfe 100644 (file)
@@ -64,6 +64,8 @@ class DocParser(object):
         parser = {
             'param': self._parse_param,
             'type': self._parse_type,
+            'in': self._parse_in,
+            'required': self._parse_required,
             'rtype': self._parse_rtype,
             'property': self._parse_property,
             'ptype': self._parse_ptype,
@@ -80,9 +82,6 @@ class DocParser(object):
         self.params.setdefault(arg, {}).update({
             'name': arg,
             'description': body,
-            'paramType': arg,
-            'required': True,
-            'allowMultiple': False
         })
 
         if 'paramType' not in self.params[arg]:
@@ -96,6 +95,22 @@ class DocParser(object):
             'dataType': body
         })
 
+    def _parse_in(self, **kwargs):
+        arg = kwargs.get('arg', None)
+        body = self._get_body(**kwargs)
+        self.params.setdefault(arg, {}).update({
+            'name': arg,
+            'paramType': body
+        })
+
+    def _parse_required(self, **kwargs):
+        arg = kwargs.get('arg', None)
+        body = self._get_body(**kwargs)
+        self.params.setdefault(arg, {}).update({
+            'name': arg,
+            'required': False if body in ['False', 'false'] else True
+        })
+
     def _parse_rtype(self, **kwargs):
         body = self._get_body(**kwargs)
         self.responseClass = body
@@ -162,13 +177,25 @@ class DocParser(object):
 
 
 class model(DocParser):
-    def __init__(self, cls=None, *args, **kwargs):
+    def __init__(self, *args, **kwargs):
         super(model, self).__init__()
-        self.id = cls.__name__
         self.args = args
         self.kwargs = kwargs
         self.required = []
+        self.cls = None
+
+    def __call__(self, *args, **kwargs):
+        if self.cls:
+            return self.cls
 
+        cls = args[0]
+        self._parse_model(cls)
+
+        return cls
+
+    def _parse_model(self, cls):
+        self.id = cls.__name__
+        self.cls = cls
         if '__init__' in dir(cls):
             self._parse_args(cls.__init__)
         self.parse_docstring(inspect.getdoc(cls))
@@ -188,7 +215,6 @@ class model(DocParser):
             self.properties.setdefault(arg, {'type': 'string', "default": default})
 
 
-
 class operation(DocParser):
     def __init__(self, nickname=None, **kwds):
         super(operation, self).__init__()
index 2a2a666..1882f00 100644 (file)
@@ -5,7 +5,7 @@ import json
 import inspect
 import tornado.web
 import tornado.template
-from tornado_swagger.settings import SWAGGER_VERSION, URL_SWAGGER_API_LIST, URL_SWAGGER_API_SPEC, models
+from settings import SWAGGER_VERSION, URL_SWAGGER_API_LIST, URL_SWAGGER_API_SPEC, models
 
 __author__ = 'serena'