From 726a8c2f61ad11bc874c6c736174420a62ca3988 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 26 Sep 2017 18:00:01 +0100 Subject: [PATCH] Refactor _load_swagger_meta factor out _handle_endpoint --- templating/matrix_templates/units.py | 238 ++++++++++++++------------- 1 file changed, 124 insertions(+), 114 deletions(-) diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index 97adc5ca..09353f97 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -23,7 +23,6 @@ file instead. from batesian.units import Units from collections import OrderedDict import logging -import inspect import json import os import re @@ -371,131 +370,142 @@ def get_example_for_response(response): class MatrixUnits(Units): def _load_swagger_meta(self, api, group_name): endpoints = [] + base_path = api.get("basePath", "") + for path in api["paths"]: for method in api["paths"][path]: - single_api = api["paths"][path][method] - full_path = api.get("basePath", "").rstrip("/") + path - endpoint = { - "title": single_api.get("summary", ""), - "deprecated": single_api.get("deprecated", False), - "desc": single_api.get("description", single_api.get("summary", "")), - "method": method.upper(), - "path": full_path.strip(), - "requires_auth": "security" in single_api, - "rate_limited": 429 in single_api.get("responses", {}), - "req_param_by_loc": {}, - "req_body_tables": [], - "res_headers": [], - "res_tables": [], - "responses": [], - "example": { - "req": "", - } - } logger.info(" ------- Endpoint: %s %s ------- " % (method, path)) - path_template = api.get("basePath", "").rstrip("/") + path - example_query_params = [] - example_body = "" + try: + endpoint = self._handle_endpoint( + api["paths"][path][method], method, + base_path.rstrip("/") + path) - for param in single_api.get("parameters", []): - # even body params should have names, otherwise the active docs don't work. - param_name = param["name"] - - try: - param_loc = param["in"] - - if param_loc == "body": - self._handle_body_param(param, endpoint) - example_body = get_example_for_param(param) - continue - - # description - desc = param.get("description", "") - if param.get("required"): - desc = "**Required.** " + desc - - # assign value expected for this param - val_type = param.get("type") # integer/string - - if param.get("enum"): - val_type = "enum" - desc += ( - " One of: %s" % json.dumps(param.get("enum")) - ) - - endpoint["req_param_by_loc"].setdefault(param_loc, []).append({ - "key": param_name, - "type": val_type, - "desc": desc - }) - - example = get_example_for_param(param) - if example is None: - continue - - if param_loc == "path": - path_template = path_template.replace( - "{%s}" % param_name, urllib.quote(example) - ) - elif param_loc == "query": - if type(example) == list: - for value in example: - example_query_params.append((param_name, value)) - else: - example_query_params.append((param_name, example)) - - except Exception, e: - raise Exception("Error handling parameter %s" % param_name, e) - # endfor[param] - - good_response = None - for code in sorted(single_api.get("responses", {}).keys()): - res = single_api["responses"][code] - if not good_response and code == 200: - good_response = res - description = res.get("description", "") - example = get_example_for_response(res) - endpoint["responses"].append({ - "code": code, - "description": description, - "example": example, - }) - - # add response params if this API has any. - if good_response: - if "schema" in good_response: - endpoint["res_tables"] = get_tables_for_response( - good_response["schema"] - ) - if "headers" in good_response: - headers = [] - for (header_name, header) in good_response["headers"].iteritems(): - headers.append({ - "key": header_name, - "type": header["type"], - "desc": header["description"], - }) - endpoint["res_headers"] = headers - - query_string = "" if len(example_query_params) == 0 else "?"+urllib.urlencode(example_query_params) - if example_body: - endpoint["example"]["req"] = "%s %s%s HTTP/1.1\nContent-Type: application/json\n\n%s" % ( - method.upper(), path_template, query_string, example_body - ) - else: - endpoint["example"]["req"] = "%s %s%s HTTP/1.1\n\n" % ( - method.upper(), path_template, query_string + endpoints.append(endpoint) + except Exception as e: + raise Exception( + "Error handling endpoint %s %s: %s" % (method, path, e), ) - - endpoints.append(endpoint) - return { "base": api.get("basePath").rstrip("/"), "group": group_name, "endpoints": endpoints, } + def _handle_endpoint(self, endpoint_swagger, method, path): + endpoint = { + "title": endpoint_swagger.get("summary", ""), + "deprecated": endpoint_swagger.get("deprecated", False), + "desc": endpoint_swagger.get("description", + endpoint_swagger.get("summary", "")), + "method": method.upper(), + "path": path.strip(), + "requires_auth": "security" in endpoint_swagger, + "rate_limited": 429 in endpoint_swagger.get("responses", {}), + "req_param_by_loc": {}, + "req_body_tables": [], + "res_headers": [], + "res_tables": [], + "responses": [], + "example": { + "req": "", + } + } + path_template = path + example_query_params = [] + example_body = "" + for param in endpoint_swagger.get("parameters", []): + # even body params should have names, otherwise the active docs don't work. + param_name = param["name"] + + try: + param_loc = param["in"] + + if param_loc == "body": + self._handle_body_param(param, endpoint) + example_body = get_example_for_param(param) + continue + + # description + desc = param.get("description", "") + if param.get("required"): + desc = "**Required.** " + desc + + # assign value expected for this param + val_type = param.get("type") # integer/string + + if param.get("enum"): + val_type = "enum" + desc += ( + " One of: %s" % json.dumps(param.get("enum")) + ) + + endpoint["req_param_by_loc"].setdefault(param_loc, []).append({ + "key": param_name, + "type": val_type, + "desc": desc + }) + + example = get_example_for_param(param) + if example is None: + continue + + if param_loc == "path": + path_template = path_template.replace( + "{%s}" % param_name, urllib.quote(example) + ) + elif param_loc == "query": + if type(example) == list: + for value in example: + example_query_params.append((param_name, value)) + else: + example_query_params.append((param_name, example)) + + except Exception, e: + raise Exception("Error handling parameter %s" % param_name, e) + # endfor[param] + good_response = None + for code in sorted(endpoint_swagger.get("responses", {}).keys()): + res = endpoint_swagger["responses"][code] + if not good_response and code == 200: + good_response = res + description = res.get("description", "") + example = get_example_for_response(res) + endpoint["responses"].append({ + "code": code, + "description": description, + "example": example, + }) + + # add response params if this API has any. + if good_response: + if "schema" in good_response: + endpoint["res_tables"] = get_tables_for_response( + good_response["schema"] + ) + if "headers" in good_response: + headers = [] + for (header_name, header) in good_response[ + "headers"].iteritems(): + headers.append({ + "key": header_name, + "type": header["type"], + "desc": header["description"], + }) + endpoint["res_headers"] = headers + query_string = "" if len( + example_query_params) == 0 else "?" + urllib.urlencode( + example_query_params) + if example_body: + endpoint["example"][ + "req"] = "%s %s%s HTTP/1.1\nContent-Type: application/json\n\n%s" % ( + method.upper(), path_template, query_string, example_body + ) + else: + endpoint["example"]["req"] = "%s %s%s HTTP/1.1\n\n" % ( + method.upper(), path_template, query_string + ) + return endpoint def _handle_body_param(self, param, endpoint_data): """Update endpoint_data object with the details of the body param