diff --git a/fixtures/petstore_spaces.json b/fixtures/petstore_spaces.json new file mode 100644 index 0000000..136b580 --- /dev/null +++ b/fixtures/petstore_spaces.json @@ -0,0 +1,175 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "license": { + "name": "MIT" + } + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1" + } + ], + "paths": { + "/pets": { + "get": { + "summary": "List all pets", + "operationId": "listPets", + "tags": [ + "pets" + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "How many items to return at one time (max 100)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "A paged array of pets", + "headers": { + "x-next": { + "description": "A link to the next page of responses", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pets" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "summary": "Create a pet", + "operationId": "createPets", + "tags": [ + "pets" + ], + "responses": { + "201": { + "description": "Null response" + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/pets/{petId}": { + "get": { + "summary": "Info for a specific pet", + "operationId": "showPetById", + "tags": [ + "pets" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "required": true, + "description": "The id of the pet to retrieve", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Expected response to a valid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pets" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Pet": { + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Pets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Pet" + } + }, + "Error": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + } \ No newline at end of file diff --git a/fixtures/petstore_tab.json b/fixtures/petstore_tab.json new file mode 100644 index 0000000..2f6fb37 --- /dev/null +++ b/fixtures/petstore_tab.json @@ -0,0 +1,175 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "license": { + "name": "MIT" + } + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1" + } + ], + "paths": { + "/pets": { + "get": { + "summary": "List all pets", + "operationId": "listPets", + "tags": [ + "pets" + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "How many items to return at one time (max 100)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "A paged array of pets", + "headers": { + "x-next": { + "description": "A link to the next page of responses", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pets" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "summary": "Create a pet", + "operationId": "createPets", + "tags": [ + "pets" + ], + "responses": { + "201": { + "description": "Null response" + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/pets/{petId}": { + "get": { + "summary": "Info for a specific pet", + "operationId": "showPetById", + "tags": [ + "pets" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "required": true, + "description": "The id of the pet to retrieve", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Expected response to a valid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pets" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Pet": { + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Pets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Pet" + } + }, + "Error": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + } \ No newline at end of file diff --git a/openapi2jsonschema/command.py b/openapi2jsonschema/command.py index 9cd1bfc..d6cc602 100644 --- a/openapi2jsonschema/command.py +++ b/openapi2jsonschema/command.py @@ -63,9 +63,13 @@ def default(output, schema, prefix, stand_alone, expanded, kubernetes, strict): response = urllib.request.urlopen(req) info("Parsing schema") - # Note that JSON is valid YAML, so we can use the YAML parser whether - # the schema is stored in JSON or YAML - data = yaml.load(response.read(), Loader=yaml.SafeLoader) + # JSON is valid YAML IF it is not indented with tabs, + # since yaml.SafeLoader doesn't handle this we load json with the json loader. + responseBody = response.read() + try: + data = json.loads(responseBody) + except ValueError as e: + data = yaml.load(responseBody, Loader=yaml.SafeLoader) if "swagger" in data: version = data["swagger"] @@ -98,8 +102,7 @@ def default(output, schema, prefix, stand_alone, expanded, kubernetes, strict): for kube_ext in type_def["x-kubernetes-group-version-kind"]: if expanded and "apiVersion" in type_def["properties"]: api_version = ( - kube_ext["group"] + "/" + - kube_ext["version"] + kube_ext["group"] + "/" + kube_ext["version"] if kube_ext["group"] else kube_ext["version"] ) @@ -115,8 +118,7 @@ def default(output, schema, prefix, stand_alone, expanded, kubernetes, strict): ) if strict: definitions = additional_properties(definitions) - definitions_file.write(json.dumps( - {"definitions": definitions}, indent=2)) + definitions_file.write(json.dumps({"definitions": definitions}, indent=2)) types = [] @@ -184,8 +186,7 @@ def default(output, schema, prefix, stand_alone, expanded, kubernetes, strict): if stand_alone: base = "file://%s/%s/" % (os.getcwd(), output) - specification = JsonRef.replace_refs( - specification, base_uri=base) + specification = JsonRef.replace_refs(specification, base_uri=base) if "additionalProperties" in specification: if specification["additionalProperties"]: diff --git a/openapi2jsonschema/test_command.py b/openapi2jsonschema/test_command.py index 3e5689a..2f58158 100644 --- a/openapi2jsonschema/test_command.py +++ b/openapi2jsonschema/test_command.py @@ -7,7 +7,11 @@ FIXTURE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../fixtures") -@pytest.mark.datafiles(os.path.join(FIXTURE_DIR, "petstore.yaml")) +@pytest.mark.datafiles( + os.path.join(FIXTURE_DIR, "petstore.yaml"), + os.path.join(FIXTURE_DIR, "petstore_spaces.json"), + os.path.join(FIXTURE_DIR, "petstore_tab.json"), +) def test_command(datafiles): runner = CliRunner() for spec in datafiles.listdir():