Skip to content

Commit

Permalink
Merge pull request #4 from henrycjc/zeusttu-25-get-schemas-from-reque…
Browse files Browse the repository at this point in the history
…st-and-response-bodies

Zeusttu 25 get schemas from request and response bodies
  • Loading branch information
henrycjc authored Dec 21, 2021
2 parents 9631d8f + 5a75b38 commit 21a538d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 4 deletions.
29 changes: 25 additions & 4 deletions openapi2jsonschema/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
allow_null_optional_fields,
change_dict_values,
append_no_duplicates,
get_request_and_response_body_components_from_paths,
)
from openapi2jsonschema.errors import UnsupportedError

Expand Down Expand Up @@ -51,8 +52,23 @@
is_flag=True,
help="Prohibits properties not in the schema (additionalProperties: false)",
)
@click.option(
"--include-bodies",
is_flag=True,
help="Include request and response bodies as if they are components",
)
@click.argument("schema", metavar="SCHEMA_URL")
def default(output, schema, prefix, stand_alone, expanded, kubernetes, no_all, strict):
def default(
output,
schema,
prefix,
stand_alone,
expanded,
kubernetes,
strict,
no_all,
include_bodies,
):
"""
Converts a valid OpenAPI specification into a set of JSON Schema files
"""
Expand Down Expand Up @@ -130,8 +146,14 @@ def default(output, schema, prefix, stand_alone, expanded, kubernetes, no_all, s
components = data["components"]["schemas"]

generated_files = []

if include_bodies:
components.update(
get_request_and_response_body_components_from_paths(data["paths"]),
)

for title in components:
kind = title.split(".")[-1].lower()
kind = title.split(".")[-1]
if kubernetes:
group = title.split(".")[-3].lower()
api_version = title.split(".")[-2].lower()
Expand Down Expand Up @@ -168,8 +190,7 @@ def default(output, schema, prefix, stand_alone, expanded, kubernetes, no_all, s
if (
kubernetes
and stand_alone
and kind
in [
and kind.lower() in [
"jsonschemaprops",
"jsonschemapropsorarray",
"customresourcevalidation",
Expand Down
48 changes: 48 additions & 0 deletions openapi2jsonschema/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env python

import re


def iteritems(d):
if hasattr(dict, "iteritems"):
Expand Down Expand Up @@ -115,3 +117,49 @@ def append_no_duplicates(obj, key, value):
obj[key] = []
if value not in obj[key]:
obj[key].append(value)


def get_components_from_body_definition(body_definition, prefix=""):
MIMETYPE_TO_TYPENAME_MAP = {
"application/json": "json",
"application/vnd.api+json": "jsonapi",
}
result = {}
for mimetype, definition in body_definition.get("content", {}).items():
type_name = MIMETYPE_TO_TYPENAME_MAP.get(
mimetype,
mimetype.replace("/", "_"),
)
if "schema" in definition:
result["{:s}{:s}".format(prefix, type_name)] = definition["schema"]
return result


def get_request_and_response_body_components_from_paths(paths):
components = {}
for path, path_definition in paths.items():
for http_method, http_method_definition in path_definition.items():
name_prefix_fmt = "paths_{:s}_{:s}_{{:s}}_".format(
# Paths "/" and "/root" will conflict,
# no idea how to solve this elegantly.
path.lstrip("/").replace("/", "_") or "root",
http_method.upper(),
)
name_prefix_fmt = re.sub(
r"\{([^:\}]+)\}",
r"_\1_",
name_prefix_fmt,
)
if "requestBody" in http_method_definition:
components.update(get_components_from_body_definition(
http_method_definition["requestBody"],
prefix=name_prefix_fmt.format("request")
))
responses = http_method_definition["responses"]
for response_code, response in responses.items():
response_name_part = "response_{}".format(response_code)
components.update(get_components_from_body_definition(
response,
prefix=name_prefix_fmt.format(response_name_part),
))
return components

0 comments on commit 21a538d

Please sign in to comment.