in samtranslator/model/api/api_generator.py [0:0]
def _openapi_postprocess(self, definition_body: Dict[str, Any]) -> Dict[str, Any]: # noqa: PLR0912
"""
Convert definitions to openapi 3 in definition body if OpenApiVersion flag is specified.
If the is swagger defined in the definition body, we treat it as a swagger spec and do not
make any openapi 3 changes to it
"""
if definition_body.get("swagger") is not None:
return definition_body
if self.feature_toggle and self.feature_toggle.is_enabled(FEATURE_FLAG_NORMALIZED_OPENAPI_VERSION):
normalized_open_api_version = definition_body.get("openapi", self.open_api_version)
elif definition_body.get("openapi") is not None and self.open_api_version is None:
normalized_open_api_version = definition_body.get("openapi")
else:
normalized_open_api_version = self.open_api_version
if normalized_open_api_version and SwaggerEditor.safe_compare_regex_with_string(
SwaggerEditor._OPENAPI_VERSION_3_REGEX, normalized_open_api_version
):
if definition_body.get("securityDefinitions"):
components = definition_body.get("components", Py27Dict())
# In the previous line, the default value `Py27Dict()` will be only returned only if `components`
# property is not in definition_body dict, but if it exist, and its value is None, so None will be
# returned and not the default value. That is why the below line is required.
components = components if components else Py27Dict()
components["securitySchemes"] = definition_body["securityDefinitions"]
definition_body["components"] = components
del definition_body["securityDefinitions"]
if definition_body.get("definitions"):
components = definition_body.get("components", Py27Dict())
# the following line to check if components is None
# is copied from the previous if...
# In the previous line, the default value `Py27Dict()` will be only returned only if `components`
# property is not in definition_body dict, but if it exist, and its value is None, so None will be
# returned and not the default value. That is why the below line is required.
components = components if components else Py27Dict()
components["schemas"] = definition_body["definitions"]
definition_body["components"] = components
del definition_body["definitions"]
# removes `consumes` and `produces` options for CORS in openapi3 and
# adds `schema` for the headers in responses for openapi3
paths = definition_body.get("paths")
if paths:
SwaggerEditor.validate_is_dict(
paths,
"Value of paths must be a dictionary according to Swagger spec.",
)
for path, path_item in paths.items():
SwaggerEditor.validate_path_item_is_dict(path_item, path)
if path_item.get("options"):
SwaggerEditor.validate_is_dict(
path_item.get("options"),
f"Value of options method for path {path} must be a "
"dictionary according to Swagger spec.",
)
options = path_item.get("options").copy()
for field, field_val in options.items():
# remove unsupported produces and consumes in options for openapi3
if field in ["produces", "consumes"]:
del definition_body["paths"][path]["options"][field]
# add schema for the headers in options section for openapi3
if field in ["responses"]:
try:
response_200_headers = dict_deep_get(field_val, "200.headers")
except InvalidValueType as ex:
raise InvalidDocumentException(
[
InvalidTemplateException(
f"Invalid responses in options method for path {path}: {ex!s}.",
)
]
) from ex
if not response_200_headers:
continue
SwaggerEditor.validate_is_dict(
response_200_headers,
f"Value of response's headers in options method for path {path} must be a "
"dictionary according to Swagger spec.",
)
for header, header_val in response_200_headers.items():
new_header_val_with_schema = Py27Dict()
new_header_val_with_schema["schema"] = header_val
definition_body["paths"][path]["options"][field]["200"]["headers"][
header
] = new_header_val_with_schema
return definition_body