Skip to content

Commit

Permalink
Add option to include request and response body schemas
Browse files Browse the repository at this point in the history
Include schemas from:

paths/<path>/<httpmethod>/requestBody/content/<mimetype>/schema
paths/<path>/<httpmethod>/responses/<httpcode>/content/<mimetype>/schema

Closes instrumenta#25

Do not downcase filenames

Closes instrumenta#20

Move new functionality to separate function

Make "content" key in body definition optional

This was committed as a GitHub review suggestion.
Commit message suggested by Github:

Update openapi2jsonschema/util.py

Co-authored-by: Adam Kitain <[email protected]>
  • Loading branch information
2 people authored and lirik90 committed Apr 1, 2024
1 parent acda895 commit a6e935a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/openapi2jsonschema/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
append_no_duplicates,
change_dict_values,
replace_int_or_string,
get_request_and_response_body_components_from_paths,
)


Expand Down Expand Up @@ -51,8 +52,13 @@
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, strict):
def default(output, schema, prefix, stand_alone, expanded, kubernetes, strict, include_bodies):
json_encoder = json.JSONEncoder(
skipkeys=False,
ensure_ascii=True,
Expand Down Expand Up @@ -157,6 +163,11 @@ def default(output, schema, prefix, stand_alone, expanded, kubernetes, strict):
else:
components = data["components"]["schemas"]

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

for title in components:
kind = title.split(".")[-1].lower()
if kubernetes:
Expand Down
48 changes: 48 additions & 0 deletions src/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 a6e935a

Please sign in to comment.