From 49fb76ff109ad0ed3f11ff189242b2bbab047892 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Fri, 1 Jan 2016 11:22:40 -0600 Subject: [PATCH] web: swagger: Add API specification --- src/rouse/web/__init__.py | 3 +- src/rouse/web/swagger.py | 46 +++++++++++++ src/rouse/web/swagger.yml | 140 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/rouse/web/swagger.py create mode 100644 src/rouse/web/swagger.yml diff --git a/src/rouse/web/__init__.py b/src/rouse/web/__init__.py index e2cfdea..8d61ae3 100644 --- a/src/rouse/web/__init__.py +++ b/src/rouse/web/__init__.py @@ -1,5 +1,5 @@ from __future__ import unicode_literals -from . import hosts +from . import hosts, swagger from milla.dispatch import routing import functools import jinja2 @@ -82,6 +82,7 @@ class Application(milla.Application): self.dispatcher = r = routing.Router() r.add_route('/', hosts.HostListController()) + r.add_route('/api-doc', swagger.SwaggerController()) r.add_route('/{host_id}', hosts.HostController()) def make_request(self, environ): diff --git a/src/rouse/web/swagger.py b/src/rouse/web/swagger.py new file mode 100644 index 0000000..416b2d1 --- /dev/null +++ b/src/rouse/web/swagger.py @@ -0,0 +1,46 @@ +from __future__ import unicode_literals +import json +import logging +import milla.controllers +import os +import yaml + + +log = logging.getLogger(__name__) + + +try: + YAMLLoader = yaml.CLoader +except AttributeError: + YAMLLoader = yaml.Loader + + +class SwaggerController(milla.controllers.HTTPVerbController): + + filename = 'swagger.yml' + + def get_spec(self): + try: + cache, mtime = self.__cache + except AttributeError: + cache, mtime = None, None + + filepath = os.path.join(os.path.dirname(__file__), self.filename) + st = os.stat(filepath) + if cache and st.st_mtime <= mtime: + return cache + log.debug('Loading Swagger specification from {}'.format(filepath)) + with open(filepath, 'rb') as f: + cache = json.dumps(yaml.load(f, Loader=YAMLLoader)) + self.__cache = cache, st.st_mtime + return cache + + def GET(self, request): + response = request.ResponseClass() + try: + response.text = self.get_spec() + except: + log.exception('Failed to load Swagger specification:') + raise milla.HTTPNotFound + response.content_type = 'application/json' + return response diff --git a/src/rouse/web/swagger.yml b/src/rouse/web/swagger.yml new file mode 100644 index 0000000..4057780 --- /dev/null +++ b/src/rouse/web/swagger.yml @@ -0,0 +1,140 @@ +swagger: '2.0' +info: + title: Rouse + version: 0.1.0 +produces: +- application/json +consumes: +- application/x-www-form-urlencoded +- application/json +tags: + name: hosts + description: Host resources +paths: + /: + get: + description: >- + Get a list of hosts + parameters: + - name: macaddr + description: Filter by MAC address + in: query + type: string + - name: ipaddr + description: Filter by IP address + in: query + type: string + - name: hostname + description: Filter by hostname + in: query + type: string + responses: + 200: + description: Host list + schema: + type: array + items: + $ref: '#/definitions/Host' + tags: + - hosts + post: + description: >- + Create a new host + parameters: + - $ref: '#parameters/macaddr!' + - $ref: '#parameters/ipaddr' + - $ref: '#parameters/hostname' + responses: + 201: + description: Host created + schema: + $ref: '#/definitions/Host' + tags: + - hosts + /{host_id}: + get: + description: >- + Get information about a host + parameters: + - $ref: '#/parameters/host_id' + responses: + 200: + description: Host information + schema: + $ref: '#/definitions/Host' + tags: + - hosts + put: + description: >- + Update host information + parameters: + - $ref: '#/parameters/host_id' + - $ref: '#/parameters/macaddr' + - $ref: '#/parameters/ipaddr' + - $ref: '#/parameters/hostname' + responses: + 204: + description: Host updated + 404: + description: Host not found + tags: + - hosts + delete: + description: >- + Delete a host + parameters: + - name: host_id + in: path + required: true + type: integer + responses: + 204: + description: Host deleted + 404: + description: Host not found + tags: + - hosts +parameters: + host_id: + name: host_id + description: Host ID + in: path + type: integer + required: true + macaddr: + name: macaddr + description: MAC address + in: formData + type: string + ipaddr: + name: ipaddr + description: IP address + in: formData + type: string + hostname: + name: hostname + description: Hostname + in: formData + type: string + macaddr!: + name: macaddr + description: MAC address + in: formData + type: string + required: true +definitions: + Host: + type: object + properties: + id: + type: integer + description: Host ID + macaddr: + type: string + description: MAC address + ipaddr: + type: string + description: IP address + hostname: + type: string + description: Hostname