Skip to content

Commit

Permalink
Support generation of OpenApi Specification 3.1.0 (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheWall89 authored Jun 25, 2023
2 parents c134be1 + 5901b10 commit 5ff6497
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 35 deletions.
11 changes: 10 additions & 1 deletion inducoapi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ def _get_parser():
default=True,
help="Do not generate schema examples",
)
p.add_argument(
"-ov",
"--openapi-version",
type=str,
metavar="STR",
default="3.1.0",
help="The version of the OpenAPI spec",
)
p.add_argument(
"-it",
"--info-title",
Expand Down Expand Up @@ -166,8 +174,9 @@ def main():
reference=args.reference,
title=args.info_title,
version=args.info_version,
openapi_version=args.openapi_version,
)
except OpenAPIValidationError as e:
except OpenAPISpecValidatorError as e:
sys.exit(f"OpenAPI validation error\n{e}")
except ValueError as e:
sys.exit(f"{e}")
Expand Down
5 changes: 4 additions & 1 deletion inducoapi/inducoapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def build_openapi(
reference: bool = False,
title: str = "Generated by InducOapi",
version: str = "v1",
openapi_version: str = "3.1.0",
) -> Dict:
"""
Builds a dict containing a valid OpenAPI description document.
Expand All @@ -95,12 +96,13 @@ def build_openapi(
:param reference: If True, generates response content schemas in 'components'
:param title: The title of the OpenAPI document (in info)
:param version: The version of the OpenAPI document (in info)
:param openapi_version: The version of the OpenAPI spec
:return: A python dict containing a valid OpenAPI description document
:raises: openapi3.SpecError if the generated OpenAPI is not valid
:raises: ValueError if the data in request/response is not a valid JSON/YAML
"""
oapi = {
"openapi": "3.0.0",
"openapi": openapi_version,
"info": {
"title": title,
"version": version,
Expand Down Expand Up @@ -172,6 +174,7 @@ def build_openapi(
"content"
] = {media_type: {"schema": _gen_schema(data, example)}}

# By default, OpenAPI spec version is detected
validate_spec(copy.deepcopy(oapi))

return oapi
121 changes: 88 additions & 33 deletions tests/test_inducoapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,106 @@
from inducoapi.inducoapi import build_openapi
from openapi_spec_validator.readers import read_from_filename

pytestmark = pytest.mark.parametrize("openapi_version", [("3.0.0"), ("3.1.0")])

def test_get_employees_200():
oapi = build_openapi("GET", "/employees", "200")
spec_dict, spec_url = read_from_filename(
"tests/test_get_employees_200.yaml"
)

def test_get_employees_200(openapi_version):
oapi = build_openapi("GET", "/employees", "200", openapi_version=openapi_version)
spec_dict, spec_url = read_from_filename("tests/test_get_employees_200.yaml")
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_get_employees_200_params():
def test_get_employees_200_params(openapi_version):
oapi = build_openapi(
"GET",
"/employees",
"200",
parameters=[("id", "path"), ("limit", "query"), ("token", "header")],
openapi_version=openapi_version,
)
spec_dict, spec_url = read_from_filename(
"tests/test_get_employees_200_params.yaml"
)
spec_dict, spec_url = read_from_filename("tests/test_get_employees_200_params.yaml")
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_get_employees_200_info():
def test_get_employees_200_info(openapi_version):
oapi = build_openapi(
"GET", "/employees", "200", title="Custom Title", version="v1-custom"
)
spec_dict, spec_url = read_from_filename(
"tests/test_get_employees_200_info.yaml"
"GET",
"/employees",
"200",
title="Custom Title",
version="v1-custom",
openapi_version=openapi_version,
)
spec_dict, spec_url = read_from_filename("tests/test_get_employees_200_info.yaml")
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_get_employees_200_response():
def test_get_employees_200_response(openapi_version):
with open("examples/employees.json") as f:
response = f.read()
oapi = build_openapi("GET", "/employees", "200", response=response)
oapi = build_openapi(
"GET", "/employees", "200", response=response, openapi_version=openapi_version
)
spec_dict, spec_url = read_from_filename(
"tests/test_get_employees_200_response.yaml"
)
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_get_employees_200_response_ref():
def test_get_employees_200_response_ref(openapi_version):
with open("examples/employees.json") as f:
response = f.read()
oapi = build_openapi(
"GET", "/employees", "200", response=response, reference=True
"GET",
"/employees",
"200",
response=response,
reference=True,
openapi_version=openapi_version,
)
spec_dict, spec_url = read_from_filename(
"tests/test_get_employees_200_response_ref.yaml"
)
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_get_employees_200_response_noexample():
def test_get_employees_200_response_noexample(openapi_version):
with open("examples/employees.json") as f:
response = f.read()
oapi = build_openapi(
"GET", "/employees", "200", response=response, example=False
"GET",
"/employees",
"200",
response=response,
example=False,
openapi_version=openapi_version,
)
spec_dict, spec_url = read_from_filename(
"tests/test_get_employees_200_response_noexample.yaml"
)
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_get_employees_200_response_yaml():
def test_get_employees_200_response_yaml(openapi_version):
with open("examples/employees.yaml") as f:
response = f.read()
oapi = build_openapi("GET", "/employees", "200", response=response)
oapi = build_openapi(
"GET", "/employees", "200", response=response, openapi_version=openapi_version
)
spec_dict, spec_url = read_from_filename(
"tests/test_get_employees_200_response.yaml"
)
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_get_employees_200_response_mediatype():
def test_get_employees_200_response_mediatype(openapi_version):
with open("examples/employees.json") as f:
response = f.read()
oapi = build_openapi(
Expand All @@ -87,54 +110,86 @@ def test_get_employees_200_response_mediatype():
"200",
response=response,
media_type="application/yaml",
openapi_version=openapi_version,
)
spec_dict, spec_url = read_from_filename(
"tests/test_get_employees_200_response_mediatype.yaml"
)
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_post_employees_201_request_response():
def test_post_employees_201_request_response(openapi_version):
with open("examples/new_employee_req.json") as f:
request = f.read()
with open("examples/new_employee_resp.json") as f:
response = f.read()
oapi = build_openapi(
"POST", "/employees", "201", request=request, response=response
"POST",
"/employees",
"201",
request=request,
response=response,
openapi_version=openapi_version,
)
spec_dict, spec_url = read_from_filename(
"tests/test_post_employees_201_request_response.yaml"
)
spec_dict["openapi"] = openapi_version
assert oapi == spec_dict


def test_post_employees_201_request_invalid_json():
def test_post_employees_201_request_invalid_json(openapi_version):
with open("tests/invalid.json") as f:
request = f.read()
with pytest.raises(ValueError) as excinfo:
build_openapi("POST", "/employees", "201", request=request)
build_openapi(
"POST",
"/employees",
"201",
request=request,
openapi_version=openapi_version,
)
assert "request" in str(excinfo)


def test_post_employees_201_request_invalid_yaml():
def test_post_employees_201_request_invalid_yaml(openapi_version):
with open("tests/invalid.yaml") as f:
request = f.read()
with pytest.raises(ValueError) as excinfo:
build_openapi("POST", "/employees", "201", request=request)
build_openapi(
"POST",
"/employees",
"201",
request=request,
openapi_version=openapi_version,
)
assert "request" in str(excinfo)


def test_post_employees_201_response_invalid_json():
def test_post_employees_201_response_invalid_json(openapi_version):
with open("tests/invalid.json") as f:
response = f.read()
with pytest.raises(ValueError) as excinfo:
build_openapi("POST", "/employees", "201", response=response)
build_openapi(
"POST",
"/employees",
"201",
response=response,
openapi_version=openapi_version,
)
assert "response" in str(excinfo)


def test_post_employees_201_response_invalid_yaml():
def test_post_employees_201_response_invalid_yaml(openapi_version):
with open("tests/invalid.yaml") as f:
response = f.read()
with pytest.raises(ValueError) as excinfo:
build_openapi("POST", "/employees", "201", response=response)
build_openapi(
"POST",
"/employees",
"201",
response=response,
openapi_version=openapi_version,
)
assert "response" in str(excinfo)

0 comments on commit 5ff6497

Please sign in to comment.