diff options
8 files changed, 106 insertions, 61 deletions
diff --git a/result_collection_api/tornado_swagger_ui/__init__.py b/result_collection_api/tornado_swagger_ui/__init__.py index 49b1b74..031a4a2 100644 --- a/result_collection_api/tornado_swagger_ui/__init__.py +++ b/result_collection_api/tornado_swagger_ui/__init__.py @@ -2,4 +2,3 @@ # -*- coding: utf-8 -*- __author__ = 'serena' - diff --git a/result_collection_api/tornado_swagger_ui/example/basic.py b/result_collection_api/tornado_swagger_ui/example/basic.py index 1731bfd..93ff00b 100644 --- a/result_collection_api/tornado_swagger_ui/example/basic.py +++ b/result_collection_api/tornado_swagger_ui/example/basic.py @@ -22,15 +22,21 @@ class PropertySubclass: class Item: """ @description: - This is an example of a model class that has parameters in its constructor - and the fields in the swagger spec are derived from the parameters to __init__. + This is an example of a model class that has parameters in its + constructor and the fields in the swagger spec are derived from + the parameters to __init__. @notes: - In this case we would have property1, name as required parameters and property3 as optional parameter. + 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, property4=None): + def __init__(self, + property1, + property2=None, + property3=None, + property4=None): self.property1 = property1 self.property2 = property2 self.property3 = property3 @@ -78,17 +84,17 @@ class GenericApiHandler(RequestHandler): pass def prepare(self): - if not (self.request.method == "GET" or self.request.method == "DELETE"): - if self.request.headers.get("Content-Type") is not None: - if self.request.headers["Content-Type"].startswith(DEFAULT_REPRESENTATION): + if self.request.method != "GET" and self.request.method != "DELETE": + self.json_args = None + content_type = self.request.headers.get("Content-Type") + if content_type is not None: + if content_type.startswith(DEFAULT_REPRESENTATION): try: self.json_args = json.loads(self.request.body) except (ValueError, KeyError, TypeError) as error: raise HTTPError(HTTP_BAD_REQUEST, "Bad Json format [{}]". format(error)) - else: - self.json_args = None def finish_request(self, json_object): self.write(json.dumps(json_object)) @@ -138,7 +144,8 @@ class ItemHandler(GenericApiHandler): @notes: get a item, - This will be added to the Implementation Notes.It lets you put very long text in your api. + This will be added to the Implementation Notes. + It lets you put very long text in your api. """ self.finish_request(items[arg].format_http()) @@ -148,8 +155,6 @@ class ItemHandler(GenericApiHandler): @description: delete a item @notes: delete a item in items - - This will be added to the Implementation Notes.It lets you put very long text in your api. """ del items[arg] self.finish_request("success") @@ -161,8 +166,7 @@ class ItemOptionParamHandler(GenericApiHandler): """ @return 200: case is created """ - print("ProjectHandler.post: %s -- %s -- %s" % (arg1, arg2, self.request.full_url())) - fs = open("/home/swagger/tornado-rest-swagger/%s/%s" % (arg1, arg2), "wb") + fs = open("/home/%s/%s" % (arg1, arg2), "wb") fs.write(self.request.body) self.write("success") @@ -193,7 +197,7 @@ class ItemQueryHandler(GenericApiHandler): res.append(value.format_http()) elif value.property2 == property2: res.append(value.format_http()) - elif items.has_key(property1): + elif property1 in items: if items.get(property1).property2 == property2: res.append(items.get(property1).format_http()) diff --git a/result_collection_api/tornado_swagger_ui/setup.py b/result_collection_api/tornado_swagger_ui/setup.py index 9765591..57dc48a 100644 --- a/result_collection_api/tornado_swagger_ui/setup.py +++ b/result_collection_api/tornado_swagger_ui/setup.py @@ -3,8 +3,8 @@ try: except ImportError: from distutils.core import setup -with open('README') as file: - long_description = file.read() +with open('README') as f: + long_description = f.read() setup(name='tornado-swagger', version='1.0', @@ -12,20 +12,19 @@ setup(name='tornado-swagger', zip_safe=False, packages=['tornado_swagger'], package_data={ - 'tornado_swagger': [ - 'static/*.*', - 'static/css/*.*', - 'static/images/*.*', - 'static/lib/*.*', - 'static/lib/shred/*.*', - ] + 'tornado_swagger': [ + 'static/*.*', + 'static/css/*.*', + 'static/images/*.*', + 'static/lib/*.*', + 'static/lib/shred/*.*' + ] }, description='Extract swagger specs from your tornado project', author='Serena Feng', license='MIT', long_description=long_description, install_requires=[ - 'tornado>=3.1', - 'epydoc>=0.3.1' - ], -) + 'tornado>=3.1', + 'epydoc>=0.3.1' + ]) diff --git a/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py b/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py index 49b1b74..031a4a2 100644 --- a/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py +++ b/result_collection_api/tornado_swagger_ui/tornado_swagger/__init__.py @@ -2,4 +2,3 @@ # -*- coding: utf-8 -*- __author__ = 'serena' - diff --git a/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py b/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py index 33c4b53..8bcb966 100644 --- a/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py +++ b/result_collection_api/tornado_swagger_ui/tornado_swagger/handlers.py @@ -2,8 +2,9 @@ # -*- coding: utf-8 -*- from tornado.web import URLSpec, StaticFileHandler -from settings import * -from views import * +from settings import default_settings, \ + SWAGGER_API_DOCS, SWAGGER_API_LIST, SWAGGER_API_SPEC +from views import SwaggerUIHandler, SwaggerResourcesHandler, SwaggerApiHandler __author__ = 'serena' @@ -12,9 +13,27 @@ def swagger_handlers(): prefix = default_settings.get('swagger_prefix', '/swagger') if prefix[-1] != '/': prefix += '/' + + def _path(suffix): + return prefix + suffix return [ - URLSpec(prefix + r'spec.html$', SwaggerUIHandler, default_settings, name=URL_SWAGGER_API_DOCS), - URLSpec(prefix + r'spec.json$', SwaggerResourcesHandler, default_settings, name=URL_SWAGGER_API_LIST), - URLSpec(prefix + r'spec$', SwaggerApiHandler, default_settings, name=URL_SWAGGER_API_SPEC), - (prefix + r'(.*\.(css|png|gif|js))', StaticFileHandler, {'path': default_settings.get('static_path')}), + URLSpec( + _path(r'spec.html$'), + SwaggerUIHandler, + default_settings, + name=SWAGGER_API_DOCS), + URLSpec( + _path(r'spec.json$'), + SwaggerResourcesHandler, + default_settings, + name=SWAGGER_API_LIST), + URLSpec( + _path(r'spec$'), + SwaggerApiHandler, + default_settings, + name=SWAGGER_API_SPEC), + ( + _path(r'(.*\.(css|png|gif|js))'), + StaticFileHandler, + {'path': default_settings.get('static_path')}), ] diff --git a/result_collection_api/tornado_swagger_ui/tornado_swagger/settings.py b/result_collection_api/tornado_swagger_ui/tornado_swagger/settings.py index bd70c17..8f43c4a 100644 --- a/result_collection_api/tornado_swagger_ui/tornado_swagger/settings.py +++ b/result_collection_api/tornado_swagger_ui/tornado_swagger/settings.py @@ -6,11 +6,12 @@ __author__ = 'serena' SWAGGER_VERSION = '1.2' -URL_SWAGGER_API_DOCS = 'swagger-api-docs' -URL_SWAGGER_API_LIST = 'swagger-api-list' -URL_SWAGGER_API_SPEC = 'swagger-api-spec' +SWAGGER_API_DOCS = 'swagger-api-docs' +SWAGGER_API_LIST = 'swagger-api-list' +SWAGGER_API_SPEC = 'swagger-api-spec' -STATIC_PATH = os.path.join(os.path.dirname(os.path.normpath(__file__)), 'static') +STATIC_PATH = os.path.join(os.path.dirname(os.path.normpath(__file__)), + 'static') default_settings = { 'base_url': '/', 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 50b2cfe..b290e05 100644 --- a/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py +++ b/result_collection_api/tornado_swagger_ui/tornado_swagger/swagger.py @@ -128,7 +128,7 @@ class DocParser(object): if code is None: self.properties.setdefault(arg, {}).update({ 'type': link - }) + }) elif code == 'list': self.properties.setdefault(arg, {}).update({ 'type': 'array', @@ -184,7 +184,7 @@ class model(DocParser): self.required = [] self.cls = None - def __call__(self, *args, **kwargs): + def __call__(self, *args): if self.cls: return self.cls @@ -206,17 +206,21 @@ class model(DocParser): argspec.args.remove("self") defaults = {} if argspec.defaults: - defaults = list(zip(argspec.args[-len(argspec.defaults):], argspec.defaults)) + defaults = list(zip(argspec.args[-len(argspec.defaults):], + argspec.defaults)) required_args_count = len(argspec.args) - len(defaults) for arg in argspec.args[:required_args_count]: self.required.append(arg) self.properties.setdefault(arg, {'type': 'string'}) for arg, default in defaults: - self.properties.setdefault(arg, {'type': 'string', "default": default}) + self.properties.setdefault(arg, { + 'type': 'string', + "default": default + }) class operation(DocParser): - def __init__(self, nickname=None, **kwds): + def __init__(self, nickname='apis', **kwds): super(operation, self).__init__() self.nickname = nickname self.func = None @@ -271,5 +275,11 @@ def docs(**opts): class Application(tornado.web.Application): - def __init__(self, handlers=None, default_host="", transforms=None, **settings): - super(Application, self).__init__(swagger_handlers() + handlers, default_host, transforms, **settings) + def __init__(self, handlers=None, + default_host="", + transforms=None, + **settings): + super(Application, self).__init__(swagger_handlers() + handlers, + default_host, + transforms, + **settings) diff --git a/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py b/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py index 1882f00..7624023 100644 --- a/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py +++ b/result_collection_api/tornado_swagger_ui/tornado_swagger/views.py @@ -5,13 +5,17 @@ import json import inspect import tornado.web import tornado.template -from settings import SWAGGER_VERSION, URL_SWAGGER_API_LIST, URL_SWAGGER_API_SPEC, models +from settings import SWAGGER_VERSION, \ + SWAGGER_API_LIST, \ + SWAGGER_API_SPEC +from settings import models __author__ = 'serena' def json_dumps(obj, pretty=False): - return json.dumps(obj, sort_keys=True, indent=4, separators=(',', ': ')) if pretty else json.dumps(obj) + return json.dumps(obj, sort_keys=True, indent=4, separators=(',', ': ')) \ + if pretty else json.dumps(obj) class SwaggerUIHandler(tornado.web.RequestHandler): @@ -22,7 +26,9 @@ class SwaggerUIHandler(tornado.web.RequestHandler): return self.static_path def get(self): - discovery_url = urlparse.urljoin(self.request.full_url(), self.reverse_url(URL_SWAGGER_API_LIST)) + discovery_url = \ + urlparse.urljoin(self.request.full_url(), + self.reverse_url(SWAGGER_API_LIST)) self.render('index.html', discovery_url=discovery_url) @@ -41,7 +47,7 @@ class SwaggerResourcesHandler(tornado.web.RequestHandler): 'produces': ["application/json"], 'description': 'Test Api Spec', 'apis': [{ - 'path': self.reverse_url(URL_SWAGGER_API_SPEC), + 'path': self.reverse_url(SWAGGER_API_SPEC), 'description': 'Test Api Spec' }] } @@ -60,11 +66,14 @@ class SwaggerApiHandler(tornado.web.RequestHandler): if apis is None: raise tornado.web.HTTPError(404) + base_path = urlparse.urljoin(self.request.full_url(), + self.base_url)[:-1] specs = { 'apiVersion': self.api_version, 'swaggerVersion': SWAGGER_VERSION, - 'basePath': urlparse.urljoin(self.request.full_url(), self.base_url)[:-1], - 'apis': [self.__get_api_spec__(path, spec, operations) for path, spec, operations in apis], + 'basePath': base_path, + 'apis': [self.__get_api_spec__(path, spec, operations) + for path, spec, operations in apis], 'models': self.__get_models_spec(models) } self.finish(json_dumps(specs, self.get_arguments('pretty'))) @@ -103,14 +112,19 @@ class SwaggerApiHandler(tornado.web.RequestHandler): @staticmethod def find_api(host_handlers): + def get_path(url, args): + return url % tuple(['{%s}' % arg for arg in args]) + + def get_operations(cls): + return [member.rest_api + for (_, member) in inspect.getmembers(cls) + if hasattr(member, 'rest_api')] + for host, handlers in host_handlers: for spec in handlers: - for (name, member) in inspect.getmembers(spec.handler_class): - if inspect.ismethod(member) and hasattr(member, 'rest_api'): - spec_path = spec._path % tuple(['{%s}' % arg for arg in member.rest_api.func_args]) - operations = [member.rest_api for (name, member) in inspect.getmembers(spec.handler_class) - if hasattr(member, 'rest_api')] - yield spec_path, spec, operations + for (_, mbr) in inspect.getmembers(spec.handler_class): + if inspect.ismethod(mbr) and hasattr(mbr, 'rest_api'): + path = get_path(spec._path, mbr.rest_api.func_args) + operations = get_operations(spec.handler_class) + yield path, spec, operations break - - |