From 83d5946dcedcc60ddca6c7538f692d37bdc873ba Mon Sep 17 00:00:00 2001 From: SerenaFeng Date: Fri, 13 May 2016 15:58:04 +0800 Subject: [PATCH] tornado_swagger_ui support query operation in "GET" method, and support methods in model 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 --- .../tornado_swagger_ui/README.md | 53 ++++++++++++++ .../tornado_swagger_ui/__init__.py | 5 ++ .../tornado_swagger_ui/example/basic.py | 81 ++++++++++++++++++++-- .../tornado_swagger_ui/tornado_swagger/__init__.py | 2 - .../tornado_swagger_ui/tornado_swagger/handlers.py | 4 +- .../tornado_swagger_ui/tornado_swagger/swagger.py | 38 ++++++++-- .../tornado_swagger_ui/tornado_swagger/views.py | 2 +- 7 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 utils/test/result_collection_api/tornado_swagger_ui/__init__.py diff --git a/utils/test/result_collection_api/tornado_swagger_ui/README.md b/utils/test/result_collection_api/tornado_swagger_ui/README.md index 707eec0a7..e90e1309a 100644 --- a/utils/test/result_collection_api/tornado_swagger_ui/README.md +++ b/utils/test/result_collection_api/tornado_swagger_ui/README.md @@ -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 index 000000000..49b1b749e --- /dev/null +++ b/utils/test/result_collection_api/tornado_swagger_ui/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +__author__ = 'serena' + diff --git a/utils/test/result_collection_api/tornado_swagger_ui/example/basic.py b/utils/test/result_collection_api/tornado_swagger_ui/example/basic.py index 20ad9cba1..1731bfd17 100644 --- a/utils/test/result_collection_api/tornado_swagger_ui/example/basic.py +++ b/utils/test/result_collection_api/tornado_swagger_ui/example/basic.py @@ -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), diff --git a/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py b/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py index 2b4f76550..49b1b749e 100644 --- a/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py +++ b/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py @@ -1,7 +1,5 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from tornado_swagger.swagger import * -from tornado_swagger.handlers import * __author__ = 'serena' diff --git a/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py b/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py index c9d49aea3..33c4b53be 100644 --- a/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py +++ b/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py @@ -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' diff --git a/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py b/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py index 0939b0d68..50b2cfe88 100644 --- a/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py +++ b/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py @@ -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__() diff --git a/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py b/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py index 2a2a66693..1882f00bf 100644 --- a/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py +++ b/utils/test/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py @@ -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' -- 2.16.6