diff --git a/hydra_openapi_parser/openapi_parser.py b/hydra_openapi_parser/openapi_parser.py index e2e92ee..19526d4 100644 --- a/hydra_openapi_parser/openapi_parser.py +++ b/hydra_openapi_parser/openapi_parser.py @@ -5,8 +5,12 @@ import yaml import json from typing import Any, Dict, Match, Optional, Tuple, Union, List, Set -from hydra_python_core.doc_writer import (HydraDoc, HydraClass, - HydraClassProp, HydraClassOp) +from hydra_python_core.doc_writer import ( + HydraDoc, + HydraClass, + HydraClassProp, + HydraClassOp, +) import sys @@ -47,7 +51,7 @@ def generate_empty_object() -> Dict[str, Any]: "op_definition": list(), "collection": False, "path": "", - "methods": set() + "methods": set(), } return object @@ -103,7 +107,7 @@ def valid_endpoint(path: str) -> str: :return: """ # "collection" or true means valid - path_ = path.split('/') + path_ = path.split("/") for subPath in path_: if "{" in subPath: if subPath != path_[len(path_) - 1]: @@ -123,7 +127,8 @@ def get_class_name(class_location: List[str]) -> str: def get_data_at_location( - class_location: List[str], doc: Dict[str, Any]) -> Dict[str, Any]: + class_location: List[str], doc: Dict[str, Any] +) -> Dict[str, Any]: """ TO get the dict at the class location provided :param class_location: list containing the class location @@ -144,24 +149,21 @@ def sanitise_path(path: str) -> str: :param path: :return: """ - path_ = path.split('/') + path_ = path.split("/") new_path = list() for subPath in path_: if "{" in subPath: pass else: new_path.append(subPath) - result = '/'.join(new_path)[1:] + result = "/".join(new_path)[1:] return result -def get_class_details(global_: Dict[str, - Any], - data: Dict[str, - Any], - class_name: str, - path="") -> None: +def get_class_details( + global_: Dict[str, Any], data: Dict[str, Any], class_name: str, path="" +) -> None: """ fetches details of class and adds the class to the dict along with the classDefinition until this point @@ -177,18 +179,16 @@ def get_class_details(global_: Dict[str, class_name = class_name # we simply check if the class has been defined or not - if not hasattr(global_[class_name]["class_definition"], 'endpoint'): + if not hasattr(global_[class_name]["class_definition"], "endpoint"): desc = data try: classDefinition = HydraClass( - class_name, - class_name, - desc["description"], - endpoint=True, - path=path) + class_name, class_name, desc["description"], endpoint=True, path=path + ) except KeyError: classDefinition = HydraClass( - class_name, class_name, class_name, endpoint=True, path=path) + class_name, class_name, class_name, endpoint=True, path=path + ) # we need to add object to global before we can attach props added = generateOrUpdateClass(class_name, False, global_, "") if added: @@ -205,16 +205,15 @@ def get_class_details(global_: Dict[str, errFlag = False if prop not in global_["class_names"]: try: - ref = properties[prop]["$ref"].split('/') + ref = properties[prop]["$ref"].split("/") if ref[0] == "#": get_class_details( global_, - get_data_at_location( - ref, - global_["doc"]), + get_data_at_location(ref, global_["doc"]), get_class_name(ref), - get_class_name(ref)) + get_class_name(ref), + ) else: vocabFlag = False except KeyError: @@ -231,15 +230,22 @@ def get_class_details(global_: Dict[str, if vocabFlag: if errFlag: global_[class_name]["prop_definition"].append( - HydraClassProp("", prop, required=flag, read=True, - write=True)) + HydraClassProp("", prop, required=flag, read=True, write=True) + ) else: global_[class_name]["prop_definition"].append( - HydraClassProp("vocab:{}".format(prop), prop, required=flag, - read=True, write=True)) + HydraClassProp( + "vocab:{}".format(prop), + prop, + required=flag, + read=True, + write=True, + ) + ) else: - global_[class_name]["prop_definition"].append(HydraClassProp( - prop, prop, required=flag, read=True, write=True)) + global_[class_name]["prop_definition"].append( + HydraClassProp(prop, prop, required=flag, read=True, write=True) + ) global_[class_name]["path"] = path global_[class_name]["class_definition"] = classDefinition global_["class_names"].add(class_name) @@ -271,9 +277,7 @@ def generateOrUpdateClass(name, collection, global_, path) -> bool: return False -def check_for_ref(global_: Dict[str, Any], - path: str, - block: Dict[str, Any]) -> str: +def check_for_ref(global_: Dict[str, Any], path: str, block: Dict[str, Any]) -> str: """ Checks for references in responses and parameters key , and adds classes to state @@ -290,27 +294,26 @@ def check_for_ref(global_: Dict[str, Any], try: try: # can only be internal - class_location = block["responses"][obj]["schema"]["$ref"].\ - split('/') + class_location = block["responses"][obj]["schema"]["$ref"].split("/") except KeyError: - class_location = \ - block["responses"][obj]["schema"]["items"]["$ref"].\ - split('/') + class_location = block["responses"][obj]["schema"]["items"][ + "$ref" + ].split("/") collection = check_collection( - schema_obj=block["responses"][obj]["schema"], - method=path) + schema_obj=block["responses"][obj]["schema"], method=path + ) success = generateOrUpdateClass( - get_class_name(class_location), collection, global_, path) + get_class_name(class_location), collection, global_, path + ) if not success: return "" get_class_details( global_, - get_data_at_location( - class_location, - global_["doc"]), + get_data_at_location(class_location, global_["doc"]), get_class_name(class_location), - path=path) + path=path, + ) return class_location[2] except KeyError: pass @@ -322,21 +325,21 @@ def check_for_ref(global_: Dict[str, Any], for obj in block["parameters"]: try: try: - class_location = obj["schema"]["$ref"].split('/') + class_location = obj["schema"]["$ref"].split("/") except KeyError: - class_location = obj["schema"]["items"]["$ref"].split('/') + class_location = obj["schema"]["items"]["$ref"].split("/") collection_ = check_collection(obj["schema"], path) success = generateOrUpdateClass( - get_class_name(class_location), collection_, global_, path) + get_class_name(class_location), collection_, global_, path + ) if not success: return "" get_class_details( global_, - get_data_at_location( - class_location, - global_["doc"]), + get_data_at_location(class_location, global_["doc"]), get_class_name(class_location), - path=path) + path=path, + ) return class_location[2] except KeyError: pass @@ -356,19 +359,28 @@ def allow_parameter(parameter: Dict[str, Any]) -> bool: # can add rules about param processing # param can be in path too , that is already handled when we declared # the class as collection from the endpoint - params_location = ["body", "integer", "string", "long", "float",\ - "boolean", "dateTime", "Date", "array"] + params_location = [ + "body", + "integer", + "string", + "long", + "float", + "boolean", + "dateTime", + "Date", + "array", + ] try: if parameter["type"] in params_location: return True except KeyError: if parameter["in"] in params_location: return True - + return False -def type_ref_mapping(type: str)->str: +def type_ref_mapping(type: str) -> str: """ Returns semantic ref for OAS data types :param type: data type @@ -383,12 +395,13 @@ def type_ref_mapping(type: str)->str: dataType_ref_map["boolean"] = "https://schema.org/Boolean" dataType_ref_map["dateTime"] = "https://schema.org/DateTime" dataType_ref_map["date"] = "https://schema.org/Date" - + return dataType_ref_map[type] -def get_parameters(global_: Dict[str, Any], - path: str, method: str, class_name: str) -> str: +def get_parameters( + global_: Dict[str, Any], path: str, method: str, class_name: str +) -> str: """ Parse paramters from method object :param global_: global state @@ -405,35 +418,34 @@ def get_parameters(global_: Dict[str, Any], if allow_parameter(parameter): try: # check if class has been pared - if parameter["schema"]["$ref"].split( - '/')[2] in global_["class_names"]: - param = "vocab:{}".format( - parameter["schema"]["$ref"].split('/')[2]) + if parameter["schema"]["$ref"].split("/")[2] in global_["class_names"]: + param = "vocab:{}".format(parameter["schema"]["$ref"].split("/")[2]) else: # if not go to that location and parse and add get_class_details( global_, - get_data_at_location( - parameter["schema"]["$ref"]), - parameter["schema"]["$ref"].split('/')[2], - path=path) - param = "vocab:{}".format( - parameter["schema"]["$ref"].split('/')[2]) + get_data_at_location(parameter["schema"]["$ref"]), + parameter["schema"]["$ref"].split("/")[2], + path=path, + ) + param = "vocab:{}".format(parameter["schema"]["$ref"].split("/")[2]) except KeyError: type = parameter["type"] if type == "array": # TODO adaptation to array representation after discussion items = parameter["items"] try: - if items["$ref"].split( - '/')[2] in global_["class_names"]: - param = "vocab" + items["$ref"].split('/')[2] + if items["$ref"].split("/")[2] in global_["class_names"]: + param = "vocab" + items["$ref"].split("/")[2] else: get_class_details( - global_, get_data_at_location( - items["$ref"]), items["$ref"].split('/')[2], path=path) - param = "vocab" + items["$ref"].split('/')[2] + global_, + get_data_at_location(items["$ref"]), + items["$ref"].split("/")[2], + path=path, + ) + param = "vocab" + items["$ref"].split("/")[2] except KeyError: param = type_ref_mapping(items["type"]) elif type == "object": @@ -444,8 +456,9 @@ def get_parameters(global_: Dict[str, Any], return param -def get_ops(global_: Dict[str, Any], path: str, - method: Dict[str, Any], class_name: str) -> None: +def get_ops( + global_: Dict[str, Any], path: str, method: Dict[str, Any], class_name: str +) -> None: """ Get operations from path object and store in global path :param global_: global state @@ -458,39 +471,44 @@ def get_ops(global_: Dict[str, Any], path: str, op_expects = None op_name = try_catch_replacement( - global_["doc"]["paths"][path][method], - "summary", - class_name) + global_["doc"]["paths"][path][method], "summary", class_name + ) op_status = list() op_expects = get_parameters(global_, path, method, class_name) try: responses = global_["doc"]["paths"][path][method]["responses"] op_returns = None for response in responses: - if response != 'default': - op_status.append({"statusCode": int( - response), - "description": responses[response]["description"]}) + if response != "default": + op_status.append( + { + "statusCode": int(response), + "description": responses[response]["description"], + } + ) try: op_returns = "vocab:{}".format( - responses[response]["schema"]["$ref"].split('/')[2]) + responses[response]["schema"]["$ref"].split("/")[2] + ) except KeyError: pass if op_returns is None: try: op_returns = "vocab:{}".format( - responses[response]["schema"]["items"]["$ref"].split('/')[2]) + responses[response]["schema"]["items"]["$ref"].split("/")[2] + ) except KeyError: op_returns = try_catch_replacement( - responses[response]["schema"], "type", None) + responses[response]["schema"], "type", None + ) except KeyError: op_returns = None if len(op_status) == 0: - op_status.append( - {"statusCode": 200, "description": "Successful Operation"}) + op_status.append({"statusCode": 200, "description": "Successful Operation"}) global_[class_name]["methods"].add(method) - global_[class_name]["op_definition"].append(HydraClassOp( - op_name, op_method.upper(), op_expects, op_returns, op_status)) + global_[class_name]["op_definition"].append( + HydraClassOp(op_name, op_method.upper(), op_expects, op_returns, op_status) + ) else: print("Method on path {} already present !".format(path)) @@ -532,8 +550,7 @@ def parse(doc: Dict[str, Any]) -> Dict[str, Any]: baseURL = try_catch_replacement(doc, "host", "localhost") name = try_catch_replacement(doc, "basePath", "api") schemes = try_catch_replacement(doc, "schemes", "http") - api_doc = HydraDoc(name, title, desc, name, - "{}://{}".format(schemes[0], baseURL)) + api_doc = HydraDoc(name, title, desc, name, "{}://{}".format(schemes[0], baseURL)) get_paths(global_) for name in global_["class_names"]: for prop in global_[name]["prop_definition"]: @@ -547,7 +564,8 @@ def parse(doc: Dict[str, Any]) -> Dict[str, Any]: api_doc.add_supported_class( global_[name]["class_definition"], global_[name]["collection"], - collection_path=global_[name]["path"]) + collection_path=global_[name]["path"], + ) generateEntrypoint(api_doc) hydra_doc = api_doc.generate() @@ -563,17 +581,19 @@ def dump_documentation(hydra_doc: Dict[str, Any]) -> str: """ dump = json.dumps(hydra_doc, indent=4, sort_keys=True) hydra_doc = '''"""\nGenerated API Documentation for Server API using - server_doc_gen.py."""\n\ndoc = {}'''.format(dump) - hydra_doc = '{}\n'.format(hydra_doc) - hydra_doc = hydra_doc.replace('true', '"true"') - hydra_doc = hydra_doc.replace('false', '"false"') - hydra_doc = hydra_doc.replace('null', '"null"') + server_doc_gen.py."""\n\ndoc = {}'''.format( + dump + ) + hydra_doc = "{}\n".format(hydra_doc) + hydra_doc = hydra_doc.replace("true", '"true"') + hydra_doc = hydra_doc.replace("false", '"false"') + hydra_doc = hydra_doc.replace("null", '"null"') return hydra_doc if __name__ == "__main__": - with open("../samples/petstore_openapi.yaml", 'r') as stream: + with open("../samples/petstore_openapi.yaml", "r") as stream: try: doc = yaml.load(stream) except yaml.YAMLError as exc: diff --git a/samples/hydra_doc_sample.py b/samples/hydra_doc_sample.py index c3773cd..5f3a373 100644 --- a/samples/hydra_doc_sample.py +++ b/samples/hydra_doc_sample.py @@ -6,46 +6,28 @@ "@context": { "ApiDocumentation": "hydra:ApiDocumentation", "description": "hydra:description", - "domain": { - "@id": "rdfs:domain", - "@type": "@id" - }, - "expects": { - "@id": "hydra:expects", - "@type": "@id" - }, + "domain": {"@id": "rdfs:domain", "@type": "@id"}, + "expects": {"@id": "hydra:expects", "@type": "@id"}, "hydra": "http://www.w3.org/ns/hydra/core#", "label": "rdfs:label", "method": "hydra:method", "possibleStatus": "hydra:possibleStatus", - "property": { - "@id": "hydra:property", - "@type": "@id" - }, - "range": { - "@id": "rdfs:range", - "@type": "@id" - }, + "property": {"@id": "hydra:property", "@type": "@id"}, + "range": {"@id": "rdfs:range", "@type": "@id"}, "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "readonly": "hydra:readonly", "required": "hydra:required", - "returns": { - "@id": "hydra:returns", - "@type": "@id" - }, + "returns": {"@id": "hydra:returns", "@type": "@id"}, "statusCode": "hydra:statusCode", "statusCodes": "hydra:statusCodes", - "subClassOf": { - "@id": "rdfs:subClassOf", - "@type": "@id" - }, + "subClassOf": {"@id": "rdfs:subClassOf", "@type": "@id"}, "supportedClass": "hydra:supportedClass", "supportedOperation": "hydra:supportedOperation", "supportedProperty": "hydra:supportedProperty", "title": "hydra:title", "vocab": "http://petstore.swagger.io/v2/vocab#", - "writeonly": "hydra:writeonly" + "writeonly": "hydra:writeonly", }, "@id": "http://petstore.swagger.io/v2/vocab", "@type": "ApiDocumentation", @@ -62,40 +44,31 @@ "expects": "vocab:Pet", "method": "POST", "possibleStatus": [ - { - "description": "Invalid input", - "statusCode": 405 - } + {"description": "Invalid input", "statusCode": 405} ], "returns": "null", - "title": "Add a new pet to the store" + "title": "Add a new pet to the store", }, { "@type": "http://schema.org/AddAction", "expects": "vocab:Pet", "method": "PUT", "possibleStatus": [ - { - "description": "Invalid ID supplied", - "statusCode": 400 - } + {"description": "Invalid ID supplied", "statusCode": 400} ], "returns": "null", - "title": "Update an existing pet" + "title": "Update an existing pet", }, { "@type": "http://schema.org/FindAction", "expects": "https://schema.org/Text", "method": "GET", "possibleStatus": [ - { - "description": "successful operation", - "statusCode": 200 - } + {"description": "successful operation", "statusCode": 200} ], "returns": "vocab:Pet", - "title": "get all pets" - } + "title": "get all pets", + }, ], "supportedProperty": [ { @@ -104,7 +77,7 @@ "readonly": "true", "required": "false", "title": "id", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -112,7 +85,7 @@ "readonly": "true", "required": "false", "title": "category", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -120,7 +93,7 @@ "readonly": "true", "required": "true", "title": "name", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -128,7 +101,7 @@ "readonly": "true", "required": "true", "title": "photoUrls", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -136,7 +109,7 @@ "readonly": "true", "required": "false", "title": "tags", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -144,10 +117,10 @@ "readonly": "true", "required": "false", "title": "status", - "writeonly": "true" - } + "writeonly": "true", + }, ], - "title": "Pet" + "title": "Pet", }, { "@id": "vocab:ApiResponse", @@ -159,13 +132,10 @@ "expects": "https://schema.org/Text", "method": "POST", "possibleStatus": [ - { - "description": "successful operation", - "statusCode": 200 - } + {"description": "successful operation", "statusCode": 200} ], "returns": "vocab:ApiResponse", - "title": "uploads an image" + "title": "uploads an image", } ], "supportedProperty": [ @@ -175,7 +145,7 @@ "readonly": "true", "required": "false", "title": "code", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -183,7 +153,7 @@ "readonly": "true", "required": "false", "title": "type", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -191,10 +161,10 @@ "readonly": "true", "required": "false", "title": "message", - "writeonly": "true" - } + "writeonly": "true", + }, ], - "title": "ApiResponse" + "title": "ApiResponse", }, { "@id": "vocab:User", @@ -206,48 +176,33 @@ "expects": "vocab:User", "method": "POST", "possibleStatus": [ - { - "description": "Successful Operation", - "statusCode": 200 - } + {"description": "Successful Operation", "statusCode": 200} ], "returns": "null", - "title": "Create user" + "title": "Create user", }, { "@type": "http://schema.org/FindAction", "expects": "https://schema.org/Text", "method": "GET", "possibleStatus": [ - { - "description": "successful operation", - "statusCode": 200 - }, - { - "description": "Invalid username supplied", - "statusCode": 400 - }, - { - "description": "User not found", - "statusCode": 404 - } + {"description": "successful operation", "statusCode": 200}, + {"description": "Invalid username supplied", "statusCode": 400}, + {"description": "User not found", "statusCode": 404}, ], "returns": "vocab:User", - "title": "Get user by user name" + "title": "Get user by user name", }, { "@type": "http://schema.org/AddAction", "expects": "vocab:User", "method": "PUT", "possibleStatus": [ - { - "description": "Invalid user supplied", - "statusCode": 400 - } + {"description": "Invalid user supplied", "statusCode": 400} ], "returns": "null", - "title": "Updated user" - } + "title": "Updated user", + }, ], "supportedProperty": [ { @@ -256,7 +211,7 @@ "readonly": "true", "required": "false", "title": "id", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -264,7 +219,7 @@ "readonly": "true", "required": "false", "title": "username", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -272,7 +227,7 @@ "readonly": "true", "required": "false", "title": "firstName", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -280,7 +235,7 @@ "readonly": "true", "required": "false", "title": "lastName", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -288,7 +243,7 @@ "readonly": "true", "required": "false", "title": "email", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -296,7 +251,7 @@ "readonly": "true", "required": "false", "title": "password", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -304,7 +259,7 @@ "readonly": "true", "required": "false", "title": "phone", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -312,10 +267,10 @@ "readonly": "true", "required": "false", "title": "userStatus", - "writeonly": "true" - } + "writeonly": "true", + }, ], - "title": "User" + "title": "User", }, { "@id": "vocab:Order", @@ -327,39 +282,24 @@ "expects": "vocab:Order", "method": "POST", "possibleStatus": [ - { - "description": "successful operation", - "statusCode": 200 - }, - { - "description": "Invalid Order", - "statusCode": 400 - } + {"description": "successful operation", "statusCode": 200}, + {"description": "Invalid Order", "statusCode": 400}, ], "returns": "vocab:Order", - "title": "Place an order for a pet" + "title": "Place an order for a pet", }, { "@type": "http://schema.org/FindAction", "expects": "https://schema.org/Integer", "method": "GET", "possibleStatus": [ - { - "description": "successful operation", - "statusCode": 200 - }, - { - "description": "Invalid ID supplied", - "statusCode": 400 - }, - { - "description": "Order not found", - "statusCode": 404 - } + {"description": "successful operation", "statusCode": 200}, + {"description": "Invalid ID supplied", "statusCode": 400}, + {"description": "Order not found", "statusCode": 404}, ], "returns": "vocab:Order", - "title": "Find purchase order by ID" - } + "title": "Find purchase order by ID", + }, ], "supportedProperty": [ { @@ -368,7 +308,7 @@ "readonly": "true", "required": "false", "title": "id", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -376,7 +316,7 @@ "readonly": "true", "required": "false", "title": "petId", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -384,7 +324,7 @@ "readonly": "true", "required": "false", "title": "quantity", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -392,7 +332,7 @@ "readonly": "true", "required": "false", "title": "shipDate", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -400,7 +340,7 @@ "readonly": "true", "required": "false", "title": "status", - "writeonly": "true" + "writeonly": "true", }, { "@type": "SupportedProperty", @@ -408,10 +348,10 @@ "readonly": "true", "required": "false", "title": "complete", - "writeonly": "true" - } + "writeonly": "true", + }, ], - "title": "Order" + "title": "Order", }, { "@id": "http://www.w3.org/ns/hydra/core#Collection", @@ -425,10 +365,10 @@ "readonly": "false", "required": "null", "title": "members", - "writeonly": "false" + "writeonly": "false", } ], - "title": "Collection" + "title": "Collection", }, { "@id": "http://www.w3.org/ns/hydra/core#Resource", @@ -436,7 +376,7 @@ "description": "null", "supportedOperation": [], "supportedProperty": [], - "title": "Resource" + "title": "Resource", }, { "@id": "vocab:PetCollection", @@ -451,7 +391,7 @@ "expects": "null", "method": "GET", "returns": "vocab:PetCollection", - "statusCodes": [] + "statusCodes": [], }, { "@id": "_:pet_create", @@ -463,10 +403,10 @@ "statusCodes": [ { "description": "If the Pet entity was createdsuccessfully.", - "statusCode": 201 + "statusCode": 201, } - ] - } + ], + }, ], "supportedProperty": [ { @@ -476,10 +416,10 @@ "readonly": "false", "required": "false", "title": "members", - "writeonly": "false" + "writeonly": "false", } ], - "title": "PetCollection" + "title": "PetCollection", }, { "@id": "vocab:UserCollection", @@ -494,7 +434,7 @@ "expects": "null", "method": "GET", "returns": "vocab:UserCollection", - "statusCodes": [] + "statusCodes": [], }, { "@id": "_:user_create", @@ -506,10 +446,10 @@ "statusCodes": [ { "description": "If the User entity was createdsuccessfully.", - "statusCode": 201 + "statusCode": 201, } - ] - } + ], + }, ], "supportedProperty": [ { @@ -519,10 +459,10 @@ "readonly": "false", "required": "false", "title": "members", - "writeonly": "false" + "writeonly": "false", } ], - "title": "UserCollection" + "title": "UserCollection", }, { "@id": "vocab:EntryPoint", @@ -536,7 +476,7 @@ "expects": "null", "method": "GET", "returns": "null", - "statusCodes": "vocab:EntryPoint" + "statusCodes": "vocab:EntryPoint", } ], "supportedProperty": [ @@ -562,15 +502,15 @@ "statusCodes": [ { "description": "successful operation", - "statusCode": 200 + "statusCode": 200, } - ] + ], } - ] + ], }, "readonly": "true", "required": "null", - "writeonly": "false" + "writeonly": "false", }, { "hydra:description": "The Order Class", @@ -594,13 +534,10 @@ "statusCodes": [ { "description": "successful operation", - "statusCode": 200 + "statusCode": 200, }, - { - "description": "Invalid Order", - "statusCode": 400 - } - ] + {"description": "Invalid Order", "statusCode": 400}, + ], }, { "@id": "find purchase order by id", @@ -613,23 +550,23 @@ "statusCodes": [ { "description": "successful operation", - "statusCode": 200 + "statusCode": 200, }, { "description": "Invalid ID supplied", - "statusCode": 400 + "statusCode": 400, }, { "description": "Order not found", - "statusCode": 404 - } - ] - } - ] + "statusCode": 404, + }, + ], + }, + ], }, "readonly": "true", "required": "null", - "writeonly": "false" + "writeonly": "false", }, { "hydra:description": "The PetCollection collection", @@ -649,7 +586,7 @@ "expects": "null", "method": "GET", "returns": "vocab:PetCollection", - "statusCodes": [] + "statusCodes": [], }, { "@id": "_:pet_create", @@ -661,15 +598,15 @@ "statusCodes": [ { "description": "If the Pet entity was createdsuccessfully.", - "statusCode": 201 + "statusCode": 201, } - ] - } - ] + ], + }, + ], }, "readonly": "true", "required": "null", - "writeonly": "false" + "writeonly": "false", }, { "hydra:description": "The UserCollection collection", @@ -689,7 +626,7 @@ "expects": "null", "method": "GET", "returns": "vocab:UserCollection", - "statusCodes": [] + "statusCodes": [], }, { "@id": "_:user_create", @@ -701,19 +638,19 @@ "statusCodes": [ { "description": "If the User entity was createdsuccessfully.", - "statusCode": 201 + "statusCode": 201, } - ] - } - ] + ], + }, + ], }, "readonly": "true", "required": "null", - "writeonly": "false" - } + "writeonly": "false", + }, ], - "title": "EntryPoint" - } + "title": "EntryPoint", + }, ], - "title": "Swagger Petstore" + "title": "Swagger Petstore", } diff --git a/setup.py b/setup.py index 4aea34f..cec29d0 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,13 @@ from setuptools import setup, find_packages setup( - name='hydra_openapi_parser', - version='0.1', + name="hydra_openapi_parser", + version="0.1", packages=find_packages(), - license='MIT', - description='A Parser from OpenAPI to Hydra specs', - long_description=open('README.md').read(), + license="MIT", + description="A Parser from OpenAPI to Hydra specs", + long_description=open("README.md").read(), long_description_content_type="text/markdown", - url='https://github.com/HTTP-APIs/hydra-openapi-parser', - zip_safe=False + url="https://github.com/HTTP-APIs/hydra-openapi-parser", + zip_safe=False, ) diff --git a/tests/test_parser.py b/tests/test_parser.py index dd6a53c..9f2f32a 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -9,9 +9,10 @@ def import_doc(): print("Importing Open Api Documentation ..") - abs_path = abspath("{}/samples/petstore_openapi.yaml".format( - dirname(dirname(__file__)))) - with open(abs_path, 'r') as stream: + abs_path = abspath( + "{}/samples/petstore_openapi.yaml".format(dirname(dirname(__file__))) + ) + with open(abs_path, "r") as stream: try: return yaml.load(stream) except yaml.YAMLError as exc: @@ -38,15 +39,15 @@ def test_generate_empty_object(self): def test_valid_endpoint(self): """Test if the endpoint is valid and can be parsed """ - path = 'A/B/{id}/C/D' + path = "A/B/{id}/C/D" result = openapi_parser.valid_endpoint(path) assert result is "False" assert isinstance(result, str) - path = 'A/B/{id}' + path = "A/B/{id}" result = openapi_parser.valid_endpoint(path) assert result is "Collection" assert isinstance(result, str) - path = 'A/B/id' + path = "A/B/id" result = openapi_parser.valid_endpoint(path) assert result is "True" assert isinstance(result, str) @@ -54,15 +55,15 @@ def test_valid_endpoint(self): def test_get_class_name(self): """Test if the class name is being extracted properly from the path """ path = "A/B/C/Pet" - path_list = path.split('/') + path_list = path.split("/") result = openapi_parser.get_class_name(path_list) assert result is path_list[3] assert isinstance(result, str) def test_get_data_from_location(self): """Test if the data from the location given is being fetched correctly""" - path = '#/definitions/Order' - path_list = path.split('/') + path = "#/definitions/Order" + path_list = path.split("/") result = openapi_parser.get_data_at_location(path_list, self.doc) response = self.doc["definitions"]["Order"] assert response is result @@ -91,9 +92,7 @@ def test_parse(self): def test_check_collection(self): """Test if collections are being identified properly""" - schema_block = { - 'type': 'array', 'items': { - '$ref': '#/definitions/Pet'}} + schema_block = {"type": "array", "items": {"$ref": "#/definitions/Pet"}} method = "/Pet" result = openapi_parser.check_collection(schema_block, method) assert isinstance(result, bool) @@ -101,13 +100,13 @@ def test_check_collection(self): def test_check_collection_false(self): "Test if non collections are identified" - schema = {'$ref': '#/definitions/User'} + schema = {"$ref": "#/definitions/User"} method = "/Pet" result = openapi_parser.check_collection(schema, method) assert isinstance(result, bool) assert not result -if __name__ == '__main__': +if __name__ == "__main__": print("Starting tests ..") unittest.main()