Skip to content

validate and validate_url shortcuts #294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ Python package

.. code:: python

from openapi_spec_validator import validate_spec
from openapi_spec_validator import validate
from openapi_spec_validator.readers import read_from_filename

spec_dict, base_uri = read_from_filename('openapi.yaml')

# If no exception is raised by validate_spec(), the spec is valid.
validate_spec(spec_dict)
# If no exception is raised by validate(), the spec is valid.
validate(spec_dict)

validate_spec({'openapi': '3.1.0'})
validate({'openapi': '3.1.0'})

Traceback (most recent call last):
...
Expand Down
20 changes: 10 additions & 10 deletions docs/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ By default, OpenAPI spec version is detected. To validate spec:

.. code:: python

from openapi_spec_validator import validate_spec
from openapi_spec_validator import validate
from openapi_spec_validator.readers import read_from_filename

spec_dict, base_uri = read_from_filename('openapi.yaml')

# If no exception is raised by validate_spec(), the spec is valid.
validate_spec(spec_dict)
# If no exception is raised by validate(), the spec is valid.
validate(spec_dict)

validate_spec({'openapi': '3.1.0'})
validate({'openapi': '3.1.0'})

Traceback (most recent call last):
...
Expand All @@ -23,28 +23,28 @@ Add ``base_uri`` to validate spec with relative files:

.. code:: python

validate_spec(spec_dict, base_uri='file:///path/to/spec/openapi.yaml')
validate(spec_dict, base_uri='file:///path/to/spec/openapi.yaml')

You can also validate spec from url:

.. code:: python

from openapi_spec_validator import validate_spec_url
from openapi_spec_validator import validate_url

# If no exception is raised by validate_spec_url(), the spec is valid.
validate_spec_url('http://example.com/openapi.json')
# If no exception is raised by validate_url(), the spec is valid.
validate_url('http://example.com/openapi.json')

In order to explicitly validate a:

* Swagger / OpenAPI 2.0 spec, import ``OpenAPIV2SpecValidator``
* OpenAPI 3.0 spec, import ``OpenAPIV30SpecValidator``
* OpenAPI 3.1 spec, import ``OpenAPIV31SpecValidator``

and pass the validator class to ``validate_spec`` or ``validate_spec_url`` function:
and pass the validator class to ``validate`` or ``validate_url`` function:

.. code:: python

validate_spec(spec_dict, cls=OpenAPIV31SpecValidator)
validate(spec_dict, cls=OpenAPIV31SpecValidator)

You can also explicitly import ``OpenAPIV3SpecValidator`` which is a shortcut to the latest v3 release.

Expand Down
4 changes: 4 additions & 0 deletions openapi_spec_validator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""OpenAPI spec validator module."""
from openapi_spec_validator.shortcuts import validate
from openapi_spec_validator.shortcuts import validate_spec
from openapi_spec_validator.shortcuts import validate_spec_url
from openapi_spec_validator.shortcuts import validate_url
from openapi_spec_validator.validation import OpenAPIV2SpecValidator
from openapi_spec_validator.validation import OpenAPIV3SpecValidator
from openapi_spec_validator.validation import OpenAPIV30SpecValidator
Expand All @@ -25,6 +27,8 @@
"OpenAPIV3SpecValidator",
"OpenAPIV30SpecValidator",
"OpenAPIV31SpecValidator",
"validate",
"validate_url",
"validate_spec",
"validate_spec_url",
]
11 changes: 4 additions & 7 deletions openapi_spec_validator/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from openapi_spec_validator.readers import read_from_filename
from openapi_spec_validator.readers import read_from_stdin
from openapi_spec_validator.shortcuts import get_validator_cls
from openapi_spec_validator.shortcuts import validate
from openapi_spec_validator.validation import OpenAPIV2SpecValidator
from openapi_spec_validator.validation import OpenAPIV30SpecValidator
from openapi_spec_validator.validation import OpenAPIV31SpecValidator
Expand Down Expand Up @@ -91,22 +91,19 @@ def main(args: Optional[Sequence[str]] = None) -> None:

# choose the validator
validators = {
"detect": None,
"2.0": OpenAPIV2SpecValidator,
"3.0": OpenAPIV30SpecValidator,
"3.1": OpenAPIV31SpecValidator,
# backward compatibility
"3.0.0": OpenAPIV30SpecValidator,
"3.1.0": OpenAPIV31SpecValidator,
}
if args_parsed.schema == "detect":
validator_cls = get_validator_cls(spec)
else:
validator_cls = validators[args_parsed.schema]
validator_cls = validators[args_parsed.schema]

validator = validator_cls(spec, base_uri=base_uri)
# validate
try:
validator.validate()
validate(spec, base_uri=base_uri, cls=validator_cls)
except ValidationError as exc:
print_validationerror(filename, exc, args_parsed.errors)
sys.exit(1)
Expand Down
39 changes: 37 additions & 2 deletions openapi_spec_validator/shortcuts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Optional
from typing import Type

from jsonschema_path import SchemaPath
from jsonschema_path.handlers import all_urls_handler
from jsonschema_path.typing import Schema

Expand Down Expand Up @@ -35,13 +36,37 @@ def get_validator_cls(spec: Schema) -> SpecValidatorType:
return SPEC2VALIDATOR[spec_version]


def validate(
spec: Schema,
base_uri: str = "",
cls: Optional[SpecValidatorType] = None,
) -> None:
if cls is None:
cls = get_validator_cls(spec)
sp = SchemaPath.from_dict(spec, base_uri=base_uri)
v = cls(sp)
return v.validate()


def validate_url(
spec_url: str,
cls: Optional[Type[SpecValidator]] = None,
) -> None:
spec = all_urls_handler(spec_url)
return validate(spec, base_uri=spec_url, cls=cls)


def validate_spec(
spec: Schema,
base_uri: str = "",
validator: Optional[SupportsValidation] = None,
cls: Optional[SpecValidatorType] = None,
spec_url: Optional[str] = None,
) -> None:
warnings.warn(
"validate_spec shortcut is deprecated. Use validate instead.",
DeprecationWarning,
)
if validator is not None:
warnings.warn(
"validator parameter is deprecated. Use cls instead.",
Expand All @@ -59,5 +84,15 @@ def validate_spec_url(
validator: Optional[SupportsValidation] = None,
cls: Optional[Type[SpecValidator]] = None,
) -> None:
spec = all_urls_handler(spec_url)
return validate_spec(spec, base_uri=spec_url, validator=validator, cls=cls)
warnings.warn(
"validate_spec_url shortcut is deprecated. Use validate_url instead.",
DeprecationWarning,
)
if validator is not None:
warnings.warn(
"validator parameter is deprecated. Use cls instead.",
DeprecationWarning,
)
spec = all_urls_handler(spec_url)
return validator.validate(spec, base_uri=spec_url)
return validate_url(spec_url, cls=cls)
1 change: 0 additions & 1 deletion openapi_spec_validator/validation/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from jsonschema.protocols import Validator
from jsonschema_path.handlers import default_handlers
from jsonschema_path.paths import SchemaPath
from jsonschema_path.typing import Schema

from openapi_spec_validator.schemas import openapi_v2_schema_validator
from openapi_spec_validator.schemas import openapi_v30_schema_validator
Expand Down
30 changes: 17 additions & 13 deletions tests/integration/test_shortcuts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
from openapi_spec_validator import OpenAPIV30SpecValidator
from openapi_spec_validator import openapi_v2_spec_validator
from openapi_spec_validator import openapi_v30_spec_validator
from openapi_spec_validator import validate
from openapi_spec_validator import validate_spec
from openapi_spec_validator import validate_spec_url
from openapi_spec_validator import validate_url
from openapi_spec_validator.validation.exceptions import OpenAPIValidationError
from openapi_spec_validator.validation.exceptions import ValidatorDetectError

Expand All @@ -15,7 +17,7 @@ def test_spec_schema_version_not_detected(self):
spec = {}

with pytest.raises(ValidatorDetectError):
validate_spec(spec)
validate(spec)


class TestLocalValidateSpecUrl:
Expand All @@ -24,7 +26,7 @@ def test_spec_schema_version_not_detected(self, factory):
spec_url = factory.spec_file_url(spec_path)

with pytest.raises(ValidatorDetectError):
validate_spec_url(spec_url)
validate_url(spec_url)


class TestLiocalValidatev2Spec:
Expand All @@ -43,8 +45,8 @@ def test_valid(self, factory, spec_file):
spec_path = self.local_test_suite_file_path(spec_file)
spec = factory.spec_from_file(spec_path)

validate_spec(spec)
validate_spec(spec, cls=OpenAPIV2SpecValidator)
validate(spec)
validate(spec, cls=OpenAPIV2SpecValidator)
with pytest.warns(DeprecationWarning):
validate_spec(spec, validator=openapi_v2_spec_validator)

Expand All @@ -59,7 +61,7 @@ def test_falied(self, factory, spec_file):
spec = factory.spec_from_file(spec_path)

with pytest.raises(OpenAPIValidationError):
validate_spec(spec, cls=OpenAPIV2SpecValidator)
validate(spec, cls=OpenAPIV2SpecValidator)
with pytest.warns(DeprecationWarning):
with pytest.raises(OpenAPIValidationError):
validate_spec(spec, validator=openapi_v2_spec_validator)
Expand All @@ -82,9 +84,10 @@ def test_valid(self, factory, spec_file):
spec = factory.spec_from_file(spec_path)
spec_url = factory.spec_file_url(spec_path)

validate_spec(spec)
validate_spec(spec, spec_url=spec_url)
validate_spec(spec, cls=OpenAPIV30SpecValidator)
validate(spec)
with pytest.warns(DeprecationWarning):
validate_spec(spec, spec_url=spec_url)
validate(spec, cls=OpenAPIV30SpecValidator)
with pytest.warns(DeprecationWarning):
validate_spec(spec, validator=openapi_v30_spec_validator)

Expand All @@ -99,7 +102,7 @@ def test_falied(self, factory, spec_file):
spec = factory.spec_from_file(spec_path)

with pytest.raises(OpenAPIValidationError):
validate_spec(spec, cls=OpenAPIV30SpecValidator)
validate(spec, cls=OpenAPIV30SpecValidator)
with pytest.warns(DeprecationWarning):
with pytest.raises(OpenAPIValidationError):
validate_spec(spec, validator=openapi_v30_spec_validator)
Expand Down Expand Up @@ -128,9 +131,10 @@ def remote_test_suite_file_path(self, test_file):
def test_valid(self, spec_file):
spec_url = self.remote_test_suite_file_path(spec_file)

validate_spec_url(spec_url)
validate_spec_url(spec_url, cls=OpenAPIV2SpecValidator)
validate_url(spec_url)
validate_url(spec_url, cls=OpenAPIV2SpecValidator)
with pytest.warns(DeprecationWarning):
validate_spec_url(spec_url)
validate_spec_url(spec_url, validator=openapi_v2_spec_validator)


Expand All @@ -157,7 +161,7 @@ def remote_test_suite_file_path(self, test_file):
def test_valid(self, spec_file):
spec_url = self.remote_test_suite_file_path(spec_file)

validate_spec_url(spec_url)
validate_spec_url(spec_url, cls=OpenAPIV30SpecValidator)
validate_url(spec_url)
validate_url(spec_url, cls=OpenAPIV30SpecValidator)
with pytest.warns(DeprecationWarning):
validate_spec_url(spec_url, validator=openapi_v30_spec_validator)
2 changes: 1 addition & 1 deletion tests/integration/validation/test_validators.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from jsonschema_path import SchemaPath
from referencing.exceptions import Unresolvable

from jsonschema_path import SchemaPath
from openapi_spec_validator import OpenAPIV2SpecValidator
from openapi_spec_validator import OpenAPIV30SpecValidator
from openapi_spec_validator import OpenAPIV31SpecValidator
Expand Down