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
  • Loading branch information
zeusttu committed May 3, 2019
1 parent a7831bc commit c34f8cb
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
45 changes: 44 additions & 1 deletion openapi2jsonschema/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import urllib
import os
import sys
import re

from jsonref import JsonRef # type: ignore
import click
Expand All @@ -16,6 +17,7 @@
allow_null_optional_fields,
change_dict_values,
append_no_duplicates,
get_components_from_body_definition,
)
from openapi2jsonschema.errors import UnsupportedError

Expand Down Expand Up @@ -48,8 +50,22 @@
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,
):
"""
Converts a valid OpenAPI specification into a set of JSON Schema files
"""
Expand Down Expand Up @@ -120,6 +136,33 @@ def default(output, schema, prefix, stand_alone, expanded, kubernetes, strict):
else:
components = data["components"]["schemas"]

if include_bodies:
for path, path_definition in data["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),
))

for title in components:
kind = title.split(".")[-1].lower()
if kubernetes:
Expand Down
16 changes: 16 additions & 0 deletions openapi2jsonschema/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,19 @@ 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["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

0 comments on commit c34f8cb

Please sign in to comment.