Skip to content

Commit

Permalink
Merge pull request #686 from python-openapi/feature/openapi-spec-vali…
Browse files Browse the repository at this point in the history
…dator-remove-deprecations

Specification validation as part of shortcuts
  • Loading branch information
p1c2u authored Oct 13, 2023
2 parents 0abae09 + 1752d35 commit 0f5ac8e
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 32 deletions.
13 changes: 6 additions & 7 deletions docs/customizations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ Customizations
Specification validation
------------------------

By default, the provided specification is validated on ``Spec`` object creation time.
By default, the specified specification is also validated.

If you know you have a valid specification already, disabling the validator can improve the performance.

.. code-block:: python
:emphasize-lines: 5
:emphasize-lines: 4
from openapi_core import Spec
spec = Spec.from_dict(
spec_dict,
validator=None,
validate_request(
request,
spec=spec,
spec_validator_cls=None,
)
Media type deserializers
Expand Down
8 changes: 8 additions & 0 deletions openapi_core/shortcuts.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def unmarshal_apicall_request(
if not issubclass(cls, RequestUnmarshaller):
raise TypeError("'cls' argument is not type of RequestUnmarshaller")
v = cls(spec, base_url=base_url, **unmarshaller_kwargs)
v.check_spec(spec)
result = v.unmarshal(request)
result.raise_for_errors()
return result
Expand All @@ -134,6 +135,7 @@ def unmarshal_webhook_request(
"'cls' argument is not type of WebhookRequestUnmarshaller"
)
v = cls(spec, base_url=base_url, **unmarshaller_kwargs)
v.check_spec(spec)
result = v.unmarshal(request)
result.raise_for_errors()
return result
Expand Down Expand Up @@ -198,6 +200,7 @@ def unmarshal_apicall_response(
if not issubclass(cls, ResponseUnmarshaller):
raise TypeError("'cls' argument is not type of ResponseUnmarshaller")
v = cls(spec, base_url=base_url, **unmarshaller_kwargs)
v.check_spec(spec)
result = v.unmarshal(request, response)
result.raise_for_errors()
return result
Expand Down Expand Up @@ -227,6 +230,7 @@ def unmarshal_webhook_response(
"'cls' argument is not type of WebhookResponseUnmarshaller"
)
v = cls(spec, base_url=base_url, **unmarshaller_kwargs)
v.check_spec(spec)
result = v.unmarshal(request, response)
result.raise_for_errors()
return result
Expand Down Expand Up @@ -378,6 +382,7 @@ def validate_apicall_request(
if not issubclass(cls, RequestValidator):
raise TypeError("'cls' argument is not type of RequestValidator")
v = cls(spec, base_url=base_url, **validator_kwargs)
v.check_spec(spec)
return v.validate(request)


Expand All @@ -402,6 +407,7 @@ def validate_webhook_request(
"'cls' argument is not type of WebhookRequestValidator"
)
v = cls(spec, base_url=base_url, **validator_kwargs)
v.check_spec(spec)
return v.validate(request)


Expand All @@ -425,6 +431,7 @@ def validate_apicall_response(
if not issubclass(cls, ResponseValidator):
raise TypeError("'cls' argument is not type of ResponseValidator")
v = cls(spec, base_url=base_url, **validator_kwargs)
v.check_spec(spec)
return v.validate(request, response)


Expand Down Expand Up @@ -452,4 +459,5 @@ def validate_webhook_response(
"'cls' argument is not type of WebhookResponseValidator"
)
v = cls(spec, base_url=base_url, **validator_kwargs)
v.check_spec(spec)
return v.validate(request, response)
6 changes: 6 additions & 0 deletions openapi_core/unmarshalling/request/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class RequestUnmarshaller(Protocol):
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
...

def check_spec(self, spec: SchemaPath) -> None:
...

def unmarshal(
self,
request: Request,
Expand All @@ -27,6 +30,9 @@ class WebhookRequestUnmarshaller(Protocol):
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
...

def check_spec(self, spec: SchemaPath) -> None:
...

def unmarshal(
self,
request: WebhookRequest,
Expand Down
4 changes: 4 additions & 0 deletions openapi_core/unmarshalling/request/unmarshallers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Optional

from jsonschema_path import SchemaPath
from openapi_spec_validator.validation.types import SpecValidatorType

from openapi_core.casting.schemas import schema_casters_factory
from openapi_core.casting.schemas.factories import SchemaCastersFactory
Expand Down Expand Up @@ -88,6 +89,7 @@ def __init__(
style_deserializers_factory: StyleDeserializersFactory = style_deserializers_factory,
media_type_deserializers_factory: MediaTypeDeserializersFactory = media_type_deserializers_factory,
schema_validators_factory: Optional[SchemaValidatorsFactory] = None,
spec_validator_cls: Optional[SpecValidatorType] = None,
format_validators: Optional[FormatValidatorsDict] = None,
extra_format_validators: Optional[FormatValidatorsDict] = None,
extra_media_type_deserializers: Optional[
Expand All @@ -108,6 +110,7 @@ def __init__(
style_deserializers_factory=style_deserializers_factory,
media_type_deserializers_factory=media_type_deserializers_factory,
schema_validators_factory=schema_validators_factory,
spec_validator_cls=spec_validator_cls,
format_validators=format_validators,
extra_format_validators=extra_format_validators,
extra_media_type_deserializers=extra_media_type_deserializers,
Expand All @@ -123,6 +126,7 @@ def __init__(
style_deserializers_factory=style_deserializers_factory,
media_type_deserializers_factory=media_type_deserializers_factory,
schema_validators_factory=schema_validators_factory,
spec_validator_cls=spec_validator_cls,
format_validators=format_validators,
extra_format_validators=extra_format_validators,
extra_media_type_deserializers=extra_media_type_deserializers,
Expand Down
6 changes: 6 additions & 0 deletions openapi_core/unmarshalling/response/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class ResponseUnmarshaller(Protocol):
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
...

def check_spec(self, spec: SchemaPath) -> None:
...

def unmarshal(
self,
request: Request,
Expand All @@ -33,6 +36,9 @@ class WebhookResponseUnmarshaller(Protocol):
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
...

def check_spec(self, spec: SchemaPath) -> None:
...

def unmarshal(
self,
request: WebhookRequest,
Expand Down
3 changes: 3 additions & 0 deletions openapi_core/unmarshalling/unmarshallers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Tuple

from jsonschema_path import SchemaPath
from openapi_spec_validator.validation.types import SpecValidatorType

from openapi_core.casting.schemas import schema_casters_factory
from openapi_core.casting.schemas.factories import SchemaCastersFactory
Expand Down Expand Up @@ -42,6 +43,7 @@ def __init__(
style_deserializers_factory: StyleDeserializersFactory = style_deserializers_factory,
media_type_deserializers_factory: MediaTypeDeserializersFactory = media_type_deserializers_factory,
schema_validators_factory: Optional[SchemaValidatorsFactory] = None,
spec_validator_cls: Optional[SpecValidatorType] = None,
format_validators: Optional[FormatValidatorsDict] = None,
extra_format_validators: Optional[FormatValidatorsDict] = None,
extra_media_type_deserializers: Optional[
Expand All @@ -64,6 +66,7 @@ def __init__(
style_deserializers_factory=style_deserializers_factory,
media_type_deserializers_factory=media_type_deserializers_factory,
schema_validators_factory=schema_validators_factory,
spec_validator_cls=spec_validator_cls,
format_validators=format_validators,
extra_format_validators=extra_format_validators,
extra_media_type_deserializers=extra_media_type_deserializers,
Expand Down
6 changes: 6 additions & 0 deletions openapi_core/validation/request/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class RequestValidator(Protocol):
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
...

def check_spec(self, spec: SchemaPath) -> None:
...

def iter_errors(
self,
request: Request,
Expand All @@ -33,6 +36,9 @@ class WebhookRequestValidator(Protocol):
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
...

def check_spec(self, spec: SchemaPath) -> None:
...

def iter_errors(
self,
request: WebhookRequest,
Expand Down
17 changes: 17 additions & 0 deletions openapi_core/validation/request/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
from typing import Optional

from jsonschema_path import SchemaPath
from openapi_spec_validator import OpenAPIV30SpecValidator
from openapi_spec_validator import OpenAPIV31SpecValidator
from openapi_spec_validator.validation.types import SpecValidatorType

from openapi_core.casting.schemas import schema_casters_factory
from openapi_core.casting.schemas.factories import SchemaCastersFactory
Expand Down Expand Up @@ -70,6 +73,7 @@ def __init__(
style_deserializers_factory: StyleDeserializersFactory = style_deserializers_factory,
media_type_deserializers_factory: MediaTypeDeserializersFactory = media_type_deserializers_factory,
schema_validators_factory: Optional[SchemaValidatorsFactory] = None,
spec_validator_cls: Optional[SpecValidatorType] = None,
format_validators: Optional[FormatValidatorsDict] = None,
extra_format_validators: Optional[FormatValidatorsDict] = None,
extra_media_type_deserializers: Optional[
Expand All @@ -84,6 +88,7 @@ def __init__(
style_deserializers_factory=style_deserializers_factory,
media_type_deserializers_factory=media_type_deserializers_factory,
schema_validators_factory=schema_validators_factory,
spec_validator_cls=spec_validator_cls,
format_validators=format_validators,
extra_format_validators=extra_format_validators,
extra_media_type_deserializers=extra_media_type_deserializers,
Expand Down Expand Up @@ -387,53 +392,65 @@ def iter_errors(self, request: WebhookRequest) -> Iterator[Exception]:


class V30RequestBodyValidator(APICallRequestBodyValidator):
spec_validator_cls = OpenAPIV30SpecValidator
schema_validators_factory = oas30_write_schema_validators_factory


class V30RequestParametersValidator(APICallRequestParametersValidator):
spec_validator_cls = OpenAPIV30SpecValidator
schema_validators_factory = oas30_write_schema_validators_factory


class V30RequestSecurityValidator(APICallRequestSecurityValidator):
spec_validator_cls = OpenAPIV30SpecValidator
schema_validators_factory = oas30_write_schema_validators_factory


class V30RequestValidator(APICallRequestValidator):
spec_validator_cls = OpenAPIV30SpecValidator
schema_validators_factory = oas30_write_schema_validators_factory


class V31RequestBodyValidator(APICallRequestBodyValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory


class V31RequestParametersValidator(APICallRequestParametersValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory


class V31RequestSecurityValidator(APICallRequestSecurityValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory


class V31RequestValidator(APICallRequestValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory
path_finder_cls = WebhookPathFinder


class V31WebhookRequestBodyValidator(WebhookRequestBodyValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory
path_finder_cls = WebhookPathFinder


class V31WebhookRequestParametersValidator(WebhookRequestParametersValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory
path_finder_cls = WebhookPathFinder


class V31WebhookRequestSecurityValidator(WebhookRequestSecurityValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory
path_finder_cls = WebhookPathFinder


class V31WebhookRequestValidator(WebhookRequestValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory
path_finder_cls = WebhookPathFinder
6 changes: 6 additions & 0 deletions openapi_core/validation/response/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class ResponseValidator(Protocol):
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
...

def check_spec(self, spec: SchemaPath) -> None:
...

def iter_errors(
self,
request: Request,
Expand All @@ -36,6 +39,9 @@ class WebhookResponseValidator(Protocol):
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
...

def check_spec(self, spec: SchemaPath) -> None:
...

def iter_errors(
self,
request: WebhookRequest,
Expand Down
11 changes: 11 additions & 0 deletions openapi_core/validation/response/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from typing import Mapping

from jsonschema_path import SchemaPath
from openapi_spec_validator import OpenAPIV30SpecValidator
from openapi_spec_validator import OpenAPIV31SpecValidator

from openapi_core.exceptions import OpenAPIError
from openapi_core.protocols import Request
Expand Down Expand Up @@ -330,36 +332,45 @@ def iter_errors(


class V30ResponseDataValidator(APICallResponseDataValidator):
spec_validator_cls = OpenAPIV30SpecValidator
schema_validators_factory = oas30_read_schema_validators_factory


class V30ResponseHeadersValidator(APICallResponseHeadersValidator):
spec_validator_cls = OpenAPIV30SpecValidator
schema_validators_factory = oas30_read_schema_validators_factory


class V30ResponseValidator(APICallResponseValidator):
spec_validator_cls = OpenAPIV30SpecValidator
schema_validators_factory = oas30_read_schema_validators_factory


class V31ResponseDataValidator(APICallResponseDataValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory


class V31ResponseHeadersValidator(APICallResponseHeadersValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory


class V31ResponseValidator(APICallResponseValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory


class V31WebhookResponseDataValidator(WebhookResponseDataValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory


class V31WebhookResponseHeadersValidator(WebhookResponseHeadersValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory


class V31WebhookResponseValidator(WebhookResponseValidator):
spec_validator_cls = OpenAPIV31SpecValidator
schema_validators_factory = oas31_schema_validators_factory
Loading

0 comments on commit 0f5ac8e

Please sign in to comment.