From 762f4903ad85c8b781d1ced367b9746feae148bf Mon Sep 17 00:00:00 2001 From: Stuart Pullinger Date: Fri, 22 Nov 2019 11:52:29 +0000 Subject: [PATCH] Update swagger generator to reference named schemas instead of inlining them. Fixes #116 --- src/swagger/swagger_generator.py | 40 ++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/swagger/swagger_generator.py b/src/swagger/swagger_generator.py index 8fe0d1e4..46a100e0 100644 --- a/src/swagger/swagger_generator.py +++ b/src/swagger/swagger_generator.py @@ -64,6 +64,10 @@ def __init__(self, entity_name, model): self.properties_dict = {} for column in model.__table__.columns: self.properties_dict[column.name] = {"type": self._map_db_type_to_json_type(str(column.type))} + self.entity_schema = {f"{SwaggerGenerator.singularise(entity_name)}": { + "type": "object", + "properties": self.properties_dict}} + self.entity_no_id_endpoint = { f"/{entity_name.lower()}": { "get": { @@ -81,8 +85,7 @@ def __init__(self, entity_name, model): "content": { "application/json": { "schema": { - "type": "object", - "properties": self.properties_dict + "$ref": f"#/components/schemas/{SwaggerGenerator.singularise(entity_name)}" } } } @@ -119,8 +122,7 @@ def __init__(self, entity_name, model): "content": { "application/json": { "schema": { - "type": "object", - "properties": self.properties_dict + "$ref": f"#/components/schemas/{SwaggerGenerator.singularise(entity_name)}" } } } @@ -142,7 +144,7 @@ def __init__(self, entity_name, model): "content": { "application/json": { "schema": { - "type": "object" + "$ref": f"#/components/schemas/{SwaggerGenerator.singularise(entity_name)}" } } } @@ -154,8 +156,7 @@ def __init__(self, entity_name, model): "content": { "application/json": { "schema": { - "type": "object", - "properties": self.properties_dict + "$ref": f"#/components/schemas/{SwaggerGenerator.singularise(entity_name)}" } } } @@ -208,8 +209,7 @@ def __init__(self, entity_name, model): "content": { "application/json": { "schema": { - "type": "object", - "properties": self.properties_dict + "$ref": f"#/components/schemas/{SwaggerGenerator.singularise(entity_name)}" } } } @@ -251,6 +251,7 @@ def __init__(self, entity_name, model): class SwaggerSpecification(object): def __init__(self): self.paths = [] + self.schemas = [] self.top_part = { 'openapi': "3.0.0", "info": { @@ -263,16 +264,24 @@ def __init__(self): "url": "http://localhost:5000" } ], - "paths": {} + "paths": {}, + "components": { + "schemas":{} + } } def add_path(self, path): self.paths.append(path) + def add_schema(self, schema): + self.schemas.append(schema) + def get_spec_as_dict(self): spec = {} for path in self.paths: self.top_part["paths"].update(path) + for schema in self.schemas: + self.top_part["components"]["schemas"].update(schema) spec.update(self.top_part) return spec @@ -292,6 +301,16 @@ def pascal_to_normal(input): words = re.findall(r"[A-Z]?[a-z]+|[A-Z]{2,}(?=[A-Z][a-z]|\d|\W|$)|\d+", input) return " ".join(map(str.lower, words)) + @staticmethod + def singularise(plural_word:str): + if plural_word.lower().endswith('ies'): + singular_word = plural_word[:-3] + ('Y' if plural_word.isupper() else 'y') + elif plural_word.lower().endswith('s'): + singular_word = plural_word[:-1] + else: + raise ValueError(f"Don't know how to singularise {plural_word}") + return singular_word + def write_swagger_spec(self): """ Writes the openapi.yaml file @@ -304,6 +323,7 @@ def write_swagger_spec(self): swagger_spec.add_path(entity.entity_count_endpoint) swagger_spec.add_path(entity.entity_id_endpoint) swagger_spec.add_path(entity.entity_no_id_endpoint) + swagger_spec.add_schema(entity.entity_schema) swagger_dict = swagger_spec.get_spec_as_dict() yaml.Dumper.ignore_aliases = lambda *args: True with open(SwaggerGenerator.FILE_PATH, "w+") as target: