diff --git a/openapi_core/__init__.py b/openapi_core/__init__.py index fe013db0..cbd7ab5b 100644 --- a/openapi_core/__init__.py +++ b/openapi_core/__init__.py @@ -12,26 +12,16 @@ from openapi_core.shortcuts import validate_webhook_request from openapi_core.shortcuts import validate_webhook_response from openapi_core.spec import Spec -from openapi_core.unmarshalling.request import RequestValidator from openapi_core.unmarshalling.request import V3RequestUnmarshaller from openapi_core.unmarshalling.request import V3WebhookRequestUnmarshaller from openapi_core.unmarshalling.request import V30RequestUnmarshaller from openapi_core.unmarshalling.request import V31RequestUnmarshaller from openapi_core.unmarshalling.request import V31WebhookRequestUnmarshaller -from openapi_core.unmarshalling.request import openapi_request_validator -from openapi_core.unmarshalling.request import openapi_v3_request_validator -from openapi_core.unmarshalling.request import openapi_v30_request_validator -from openapi_core.unmarshalling.request import openapi_v31_request_validator -from openapi_core.unmarshalling.response import ResponseValidator from openapi_core.unmarshalling.response import V3ResponseUnmarshaller from openapi_core.unmarshalling.response import V3WebhookResponseUnmarshaller from openapi_core.unmarshalling.response import V30ResponseUnmarshaller from openapi_core.unmarshalling.response import V31ResponseUnmarshaller from openapi_core.unmarshalling.response import V31WebhookResponseUnmarshaller -from openapi_core.unmarshalling.response import openapi_response_validator -from openapi_core.unmarshalling.response import openapi_v3_response_validator -from openapi_core.unmarshalling.response import openapi_v30_response_validator -from openapi_core.unmarshalling.response import openapi_v31_response_validator from openapi_core.validation.request import V3RequestValidator from openapi_core.validation.request import V3WebhookRequestValidator from openapi_core.validation.request import V30RequestValidator @@ -83,14 +73,4 @@ "V3ResponseValidator", "V3WebhookRequestValidator", "V3WebhookResponseValidator", - "RequestValidator", - "ResponseValidator", - "openapi_v3_request_validator", - "openapi_v30_request_validator", - "openapi_v31_request_validator", - "openapi_request_validator", - "openapi_v3_response_validator", - "openapi_v30_response_validator", - "openapi_v31_response_validator", - "openapi_response_validator", ] diff --git a/openapi_core/deserializing/media_types/factories.py b/openapi_core/deserializing/media_types/factories.py index 2008c54c..f35257b2 100644 --- a/openapi_core/deserializing/media_types/factories.py +++ b/openapi_core/deserializing/media_types/factories.py @@ -1,5 +1,3 @@ -import warnings -from typing import Dict from typing import Optional from openapi_core.deserializing.media_types.datatypes import ( @@ -17,20 +15,10 @@ class MediaTypeDeserializersFactory: def __init__( self, media_type_deserializers: Optional[MediaTypeDeserializersDict] = None, - custom_deserializers: Optional[MediaTypeDeserializersDict] = None, ): if media_type_deserializers is None: media_type_deserializers = {} self.media_type_deserializers = media_type_deserializers - if custom_deserializers is None: - custom_deserializers = {} - else: - warnings.warn( - "custom_deserializers is deprecated. " - "Use extra_media_type_deserializers.", - DeprecationWarning, - ) - self.custom_deserializers = custom_deserializers def create( self, @@ -53,8 +41,6 @@ def get_deserializer_callable( mimetype: str, extra_media_type_deserializers: MediaTypeDeserializersDict, ) -> Optional[DeserializerCallable]: - if mimetype in self.custom_deserializers: - return self.custom_deserializers[mimetype] if mimetype in extra_media_type_deserializers: return extra_media_type_deserializers[mimetype] return self.media_type_deserializers.get(mimetype) diff --git a/openapi_core/shortcuts.py b/openapi_core/shortcuts.py index 9f6c2c55..b4f8a6f5 100644 --- a/openapi_core/shortcuts.py +++ b/openapi_core/shortcuts.py @@ -1,12 +1,9 @@ """OpenAPI core shortcuts module""" -import warnings from typing import Any from typing import Dict from typing import Optional from typing import Union -from lazy_object_proxy import Proxy - from openapi_core.exceptions import SpecError from openapi_core.finders import SpecClasses from openapi_core.finders import SpecFinder @@ -23,9 +20,6 @@ from openapi_core.unmarshalling.request.protocols import ( WebhookRequestUnmarshaller, ) -from openapi_core.unmarshalling.request.proxies import ( - SpecRequestValidatorProxy, -) from openapi_core.unmarshalling.request.types import AnyRequestUnmarshallerType from openapi_core.unmarshalling.request.types import RequestUnmarshallerType from openapi_core.unmarshalling.request.types import ( @@ -41,9 +35,6 @@ from openapi_core.unmarshalling.response.protocols import ( WebhookResponseUnmarshaller, ) -from openapi_core.unmarshalling.response.proxies import ( - SpecResponseValidatorProxy, -) from openapi_core.unmarshalling.response.types import ( AnyResponseUnmarshallerType, ) @@ -287,56 +278,14 @@ def validate_request( request: AnyRequest, spec: Spec, base_url: Optional[str] = None, - validator: Optional[SpecRequestValidatorProxy] = None, cls: Optional[AnyRequestValidatorType] = None, **validator_kwargs: Any, ) -> Optional[RequestUnmarshalResult]: - if isinstance(spec, (Request, WebhookRequest)) and isinstance( - request, Spec - ): - warnings.warn( - "spec parameter as a first argument is deprecated. " - "Move it to second argument instead.", - DeprecationWarning, - ) - request, spec = spec, request - if not isinstance(request, (Request, WebhookRequest)): raise TypeError("'request' argument is not type of (Webhook)Request") if not isinstance(spec, Spec): raise TypeError("'spec' argument is not type of Spec") - if validator is not None and isinstance(request, Request): - warnings.warn( - "validator parameter is deprecated. Use cls instead.", - DeprecationWarning, - ) - result = validator.validate(spec, request, base_url=base_url) - result.raise_for_errors() - return result - - # redirect to unmarshaller for backward compatibility - if cls is None or issubclass( - cls, (RequestUnmarshaller, WebhookRequestUnmarshaller) - ): - result = unmarshal_request( - request, - spec=spec, - base_url=base_url, - cls=cls, - **validator_kwargs, - ) - - def return_result() -> RequestUnmarshalResult: - warnings.warn( - "validate_request is deprecated for unmarshalling data " - "and it will not return any result in the future. " - "Use unmarshal_request function instead.", - DeprecationWarning, - ) - return result - - return Proxy(return_result) # type: ignore if isinstance(request, WebhookRequest): if cls is None or issubclass(cls, WebhookRequestValidator): validate_webhook_request( @@ -370,23 +319,9 @@ def validate_response( response: Union[Response, Request, WebhookRequest], spec: Union[Spec, Response], base_url: Optional[str] = None, - validator: Optional[SpecResponseValidatorProxy] = None, cls: Optional[AnyResponseValidatorType] = None, **validator_kwargs: Any, ) -> Optional[ResponseUnmarshalResult]: - if ( - isinstance(request, Spec) - and isinstance(response, (Request, WebhookRequest)) - and isinstance(spec, Response) - ): - warnings.warn( - "spec parameter as a first argument is deprecated. " - "Move it to third argument instead.", - DeprecationWarning, - ) - args = request, response, spec - spec, request, response = args - if not isinstance(request, (Request, WebhookRequest)): raise TypeError("'request' argument is not type of (Webhook)Request") if not isinstance(response, Response): @@ -394,38 +329,6 @@ def validate_response( if not isinstance(spec, Spec): raise TypeError("'spec' argument is not type of Spec") - if validator is not None and isinstance(request, Request): - warnings.warn( - "validator parameter is deprecated. Use cls instead.", - DeprecationWarning, - ) - result = validator.validate(spec, request, response, base_url=base_url) - result.raise_for_errors() - return result - - # redirect to unmarshaller for backward compatibility - if cls is None or issubclass( - cls, (ResponseUnmarshaller, WebhookResponseUnmarshaller) - ): - result = unmarshal_response( - request, - response, - spec=spec, - base_url=base_url, - cls=cls, - **validator_kwargs, - ) - - def return_result() -> ResponseUnmarshalResult: - warnings.warn( - "validate_response is deprecated for unmarshalling data " - "and it will not return any result in the future. " - "Use unmarshal_response function instead.", - DeprecationWarning, - ) - return result - - return Proxy(return_result) # type: ignore if isinstance(request, WebhookRequest): if cls is None or issubclass(cls, WebhookResponseValidator): validate_webhook_response( diff --git a/openapi_core/spec/paths.py b/openapi_core/spec/paths.py index 60891420..db0aee44 100644 --- a/openapi_core/spec/paths.py +++ b/openapi_core/spec/paths.py @@ -1,16 +1,11 @@ -import warnings from typing import Any -from typing import Dict from typing import Hashable from typing import Mapping -from typing import Optional from typing import Type from typing import TypeVar from jsonschema_spec import SchemaPath -from jsonschema_spec import default_handlers from openapi_spec_validator.validation import openapi_spec_validator_proxy -from openapi_spec_validator.validation.protocols import SupportsValidation TSpec = TypeVar("TSpec", bound="Spec") @@ -18,30 +13,6 @@ class Spec(SchemaPath): - @classmethod - def create( - cls: Type[TSpec], - data: Mapping[Hashable, Any], - *args: Any, - url: str = "", - ref_resolver_handlers: Dict[str, Any] = default_handlers, - separator: str = SPEC_SEPARATOR, - validator: Optional[SupportsValidation] = openapi_spec_validator_proxy, - ) -> TSpec: - warnings.warn( - "Spec.create method is deprecated. Use Spec.from_dict instead.", - DeprecationWarning, - ) - - return cls.from_dict( - data, - *args, - spec_url=url, - ref_resolver_handlers=ref_resolver_handlers, - separator=separator, - validator=validator, - ) - @classmethod def from_dict( cls: Type[TSpec], diff --git a/openapi_core/spec/shortcuts.py b/openapi_core/spec/shortcuts.py deleted file mode 100644 index b8ac1bb4..00000000 --- a/openapi_core/spec/shortcuts.py +++ /dev/null @@ -1,36 +0,0 @@ -"""OpenAPI core spec shortcuts module""" -import warnings -from typing import Any -from typing import Dict -from typing import Hashable -from typing import Mapping -from typing import Optional - -from jsonschema_spec import default_handlers -from openapi_spec_validator.validation import openapi_spec_validator_proxy -from openapi_spec_validator.validation.protocols import SupportsValidation - -from openapi_core.spec.paths import Spec - - -def create_spec( - spec_dict: Mapping[Hashable, Any], - spec_url: str = "", - handlers: Dict[str, Any] = default_handlers, - validate_spec: bool = True, -) -> Spec: - warnings.warn( - "create_spec function is deprecated. Use Spec.from_dict instead.", - DeprecationWarning, - ) - - validator: Optional[SupportsValidation] = None - if validate_spec: - validator = openapi_spec_validator_proxy - - return Spec.from_dict( - spec_dict, - spec_url=spec_url, - ref_resolver_handlers=handlers, - validator=validator, - ) diff --git a/openapi_core/unmarshalling/request/__init__.py b/openapi_core/unmarshalling/request/__init__.py index 710f17df..ddf7207a 100644 --- a/openapi_core/unmarshalling/request/__init__.py +++ b/openapi_core/unmarshalling/request/__init__.py @@ -1,14 +1,4 @@ """OpenAPI core unmarshalling request module""" -from openapi_core.unmarshalling.request.proxies import ( - DetectSpecRequestValidatorProxy, -) -from openapi_core.unmarshalling.request.proxies import ( - SpecRequestValidatorProxy, -) -from openapi_core.unmarshalling.request.unmarshallers import ( - APICallRequestUnmarshaller, -) -from openapi_core.unmarshalling.request.unmarshallers import RequestValidator from openapi_core.unmarshalling.request.unmarshallers import ( V30RequestUnmarshaller, ) @@ -18,49 +8,15 @@ from openapi_core.unmarshalling.request.unmarshallers import ( V31WebhookRequestUnmarshaller, ) -from openapi_core.unmarshalling.schemas import ( - oas30_write_schema_unmarshallers_factory, -) -from openapi_core.unmarshalling.schemas import ( - oas31_schema_unmarshallers_factory, -) __all__ = [ + "V3RequestUnmarshaller", + "V3WebhookRequestUnmarshaller", "V30RequestUnmarshaller", "V31RequestUnmarshaller", "V31WebhookRequestUnmarshaller", - "RequestValidator", - "openapi_v30_request_validator", - "openapi_v31_request_validator", - "openapi_v3_request_validator", - "openapi_request_validator", ] # alias to the latest v3 version V3RequestUnmarshaller = V31RequestUnmarshaller V3WebhookRequestUnmarshaller = V31WebhookRequestUnmarshaller - -# spec validators -openapi_v30_request_validator = SpecRequestValidatorProxy( - APICallRequestUnmarshaller, - schema_unmarshallers_factory=oas30_write_schema_unmarshallers_factory, - deprecated="openapi_v30_request_validator", - use="V30RequestValidator", -) -openapi_v31_request_validator = SpecRequestValidatorProxy( - APICallRequestUnmarshaller, - schema_unmarshallers_factory=oas31_schema_unmarshallers_factory, - deprecated="openapi_v31_request_validator", - use="V31RequestValidator", -) - -# spec validators alias to the latest v3 version -openapi_v3_request_validator = openapi_v31_request_validator - -# detect version spec -openapi_request_validator = DetectSpecRequestValidatorProxy( - { - ("openapi", "3.0"): openapi_v30_request_validator, - ("openapi", "3.1"): openapi_v31_request_validator, - }, -) diff --git a/openapi_core/unmarshalling/request/proxies.py b/openapi_core/unmarshalling/request/proxies.py deleted file mode 100644 index 04024c1a..00000000 --- a/openapi_core/unmarshalling/request/proxies.py +++ /dev/null @@ -1,115 +0,0 @@ -"""OpenAPI spec validator validation proxies module.""" -import warnings -from typing import TYPE_CHECKING -from typing import Any -from typing import Iterator -from typing import Mapping -from typing import Optional -from typing import Tuple -from typing import Type - -from openapi_core.exceptions import SpecError -from openapi_core.protocols import Request -from openapi_core.spec import Spec -from openapi_core.unmarshalling.request.datatypes import RequestUnmarshalResult - -if TYPE_CHECKING: - from openapi_core.unmarshalling.request.unmarshallers import ( - APICallRequestUnmarshaller, - ) - - -class SpecRequestValidatorProxy: - def __init__( - self, - unmarshaller_cls: Type["APICallRequestUnmarshaller"], - deprecated: str = "RequestValidator", - use: Optional[str] = None, - **unmarshaller_kwargs: Any, - ): - self.unmarshaller_cls = unmarshaller_cls - self.unmarshaller_kwargs = unmarshaller_kwargs - - self.deprecated = deprecated - self.use = use or self.unmarshaller_cls.__name__ - - def validate( - self, - spec: Spec, - request: Request, - base_url: Optional[str] = None, - ) -> "RequestUnmarshalResult": - warnings.warn( - f"{self.deprecated} is deprecated. Use {self.use} instead.", - DeprecationWarning, - ) - unmarshaller = self.unmarshaller_cls( - spec, base_url=base_url, **self.unmarshaller_kwargs - ) - return unmarshaller.unmarshal(request) - - def is_valid( - self, - spec: Spec, - request: Request, - base_url: Optional[str] = None, - ) -> bool: - unmarshaller = self.unmarshaller_cls( - spec, base_url=base_url, **self.unmarshaller_kwargs - ) - error = next(unmarshaller.iter_errors(request), None) - return error is None - - def iter_errors( - self, - spec: Spec, - request: Request, - base_url: Optional[str] = None, - ) -> Iterator[Exception]: - unmarshaller = self.unmarshaller_cls( - spec, base_url=base_url, **self.unmarshaller_kwargs - ) - yield from unmarshaller.iter_errors(request) - - -class DetectSpecRequestValidatorProxy: - def __init__( - self, choices: Mapping[Tuple[str, str], SpecRequestValidatorProxy] - ): - self.choices = choices - - def detect(self, spec: Spec) -> SpecRequestValidatorProxy: - for (key, value), validator in self.choices.items(): - if key in spec and spec[key].startswith(value): - return validator - raise SpecError("Spec schema version not detected") - - def validate( - self, - spec: Spec, - request: Request, - base_url: Optional[str] = None, - ) -> "RequestUnmarshalResult": - validator = self.detect(spec) - return validator.validate(spec, request, base_url=base_url) - - def is_valid( - self, - spec: Spec, - request: Request, - base_url: Optional[str] = None, - ) -> bool: - validator = self.detect(spec) - error = next( - validator.iter_errors(spec, request, base_url=base_url), None - ) - return error is None - - def iter_errors( - self, - spec: Spec, - request: Request, - base_url: Optional[str] = None, - ) -> Iterator[Exception]: - validator = self.detect(spec) - yield from validator.iter_errors(spec, request, base_url=base_url) diff --git a/openapi_core/unmarshalling/request/unmarshallers.py b/openapi_core/unmarshalling/request/unmarshallers.py index 96b0b76e..ac2bbf99 100644 --- a/openapi_core/unmarshalling/request/unmarshallers.py +++ b/openapi_core/unmarshalling/request/unmarshallers.py @@ -1,4 +1,3 @@ -from typing import Any from typing import Optional from openapi_core.casting.schemas import schema_casters_factory @@ -26,9 +25,6 @@ from openapi_core.spec import Spec from openapi_core.templating.paths.exceptions import PathError from openapi_core.unmarshalling.request.datatypes import RequestUnmarshalResult -from openapi_core.unmarshalling.request.proxies import ( - SpecRequestValidatorProxy, -) from openapi_core.unmarshalling.schemas import ( oas30_write_schema_unmarshallers_factory, ) @@ -428,20 +424,3 @@ class V31WebhookRequestUnmarshaller( V31WebhookRequestValidator, WebhookRequestUnmarshaller ): schema_unmarshallers_factory = oas31_schema_unmarshallers_factory - - -# backward compatibility -class RequestValidator(SpecRequestValidatorProxy): - def __init__( - self, - schema_unmarshallers_factory: "SchemaUnmarshallersFactory", - **kwargs: Any, - ): - super().__init__( - APICallRequestUnmarshaller, - schema_validators_factory=( - schema_unmarshallers_factory.schema_validators_factory - ), - schema_unmarshallers_factory=schema_unmarshallers_factory, - **kwargs, - ) diff --git a/openapi_core/unmarshalling/response/__init__.py b/openapi_core/unmarshalling/response/__init__.py index 60ec202f..998b202c 100644 --- a/openapi_core/unmarshalling/response/__init__.py +++ b/openapi_core/unmarshalling/response/__init__.py @@ -1,14 +1,4 @@ """OpenAPI core unmarshalling response module""" -from openapi_core.unmarshalling.response.proxies import ( - DetectResponseValidatorProxy, -) -from openapi_core.unmarshalling.response.proxies import ( - SpecResponseValidatorProxy, -) -from openapi_core.unmarshalling.response.unmarshallers import ( - APICallResponseUnmarshaller, -) -from openapi_core.unmarshalling.response.unmarshallers import ResponseValidator from openapi_core.unmarshalling.response.unmarshallers import ( V30ResponseUnmarshaller, ) @@ -18,50 +8,15 @@ from openapi_core.unmarshalling.response.unmarshallers import ( V31WebhookResponseUnmarshaller, ) -from openapi_core.unmarshalling.schemas import ( - oas30_read_schema_unmarshallers_factory, -) -from openapi_core.unmarshalling.schemas import ( - oas31_schema_unmarshallers_factory, -) __all__ = [ + "V3ResponseUnmarshaller", + "V3WebhookResponseUnmarshaller", "V30ResponseUnmarshaller", "V31ResponseUnmarshaller", "V31WebhookResponseUnmarshaller", - "ResponseValidator", - "openapi_v30_response_validator", - "openapi_v31_response_validator", - "openapi_v3_response_validator", - "openapi_response_validator", ] # alias to the latest v3 version V3ResponseUnmarshaller = V31ResponseUnmarshaller V3WebhookResponseUnmarshaller = V31WebhookResponseUnmarshaller - -# spec validators -openapi_v30_response_validator = SpecResponseValidatorProxy( - APICallResponseUnmarshaller, - schema_unmarshallers_factory=oas30_read_schema_unmarshallers_factory, - deprecated="openapi_v30_response_validator", - use="V30ResponseUnmarshaller", -) - -openapi_v31_response_validator = SpecResponseValidatorProxy( - APICallResponseUnmarshaller, - schema_unmarshallers_factory=oas31_schema_unmarshallers_factory, - deprecated="openapi_v31_response_validator", - use="V31ResponseUnmarshaller", -) - -# spec validators alias to the latest v3 version -openapi_v3_response_validator = openapi_v31_response_validator - -# detect version spec -openapi_response_validator = DetectResponseValidatorProxy( - { - ("openapi", "3.0"): openapi_v30_response_validator, - ("openapi", "3.1"): openapi_v31_response_validator, - }, -) diff --git a/openapi_core/unmarshalling/response/proxies.py b/openapi_core/unmarshalling/response/proxies.py deleted file mode 100644 index 5d364386..00000000 --- a/openapi_core/unmarshalling/response/proxies.py +++ /dev/null @@ -1,130 +0,0 @@ -"""OpenAPI spec validator validation proxies module.""" -import warnings -from typing import TYPE_CHECKING -from typing import Any -from typing import Iterator -from typing import Mapping -from typing import Optional -from typing import Tuple -from typing import Type - -from openapi_core.exceptions import SpecError -from openapi_core.protocols import Request -from openapi_core.protocols import Response -from openapi_core.spec import Spec -from openapi_core.unmarshalling.response.datatypes import ( - ResponseUnmarshalResult, -) - -if TYPE_CHECKING: - from openapi_core.unmarshalling.response.unmarshallers import ( - APICallResponseUnmarshaller, - ) - - -class SpecResponseValidatorProxy: - def __init__( - self, - unmarshaller_cls: Type["APICallResponseUnmarshaller"], - deprecated: str = "ResponseValidator", - use: Optional[str] = None, - **unmarshaller_kwargs: Any, - ): - self.unmarshaller_cls = unmarshaller_cls - self.unmarshaller_kwargs = unmarshaller_kwargs - - self.deprecated = deprecated - self.use = use or self.unmarshaller_cls.__name__ - - def validate( - self, - spec: Spec, - request: Request, - response: Response, - base_url: Optional[str] = None, - ) -> "ResponseUnmarshalResult": - warnings.warn( - f"{self.deprecated} is deprecated. Use {self.use} instead.", - DeprecationWarning, - ) - unmarshaller = self.unmarshaller_cls( - spec, base_url=base_url, **self.unmarshaller_kwargs - ) - return unmarshaller.unmarshal(request, response) - - def is_valid( - self, - spec: Spec, - request: Request, - response: Response, - base_url: Optional[str] = None, - ) -> bool: - unmarshaller = self.unmarshaller_cls( - spec, base_url=base_url, **self.unmarshaller_kwargs - ) - error = next( - unmarshaller.iter_errors(request, response), - None, - ) - return error is None - - def iter_errors( - self, - spec: Spec, - request: Request, - response: Response, - base_url: Optional[str] = None, - ) -> Iterator[Exception]: - unmarshaller = self.unmarshaller_cls( - spec, base_url=base_url, **self.unmarshaller_kwargs - ) - yield from unmarshaller.iter_errors(request, response) - - -class DetectResponseValidatorProxy: - def __init__( - self, choices: Mapping[Tuple[str, str], SpecResponseValidatorProxy] - ): - self.choices = choices - - def detect(self, spec: Spec) -> SpecResponseValidatorProxy: - for (key, value), validator in self.choices.items(): - if key in spec and spec[key].startswith(value): - return validator - raise SpecError("Spec schema version not detected") - - def validate( - self, - spec: Spec, - request: Request, - response: Response, - base_url: Optional[str] = None, - ) -> "ResponseUnmarshalResult": - validator = self.detect(spec) - return validator.validate(spec, request, response, base_url=base_url) - - def is_valid( - self, - spec: Spec, - request: Request, - response: Response, - base_url: Optional[str] = None, - ) -> bool: - validator = self.detect(spec) - error = next( - validator.iter_errors(spec, request, response, base_url=base_url), - None, - ) - return error is None - - def iter_errors( - self, - spec: Spec, - request: Request, - response: Response, - base_url: Optional[str] = None, - ) -> Iterator[Exception]: - validator = self.detect(spec) - yield from validator.iter_errors( - spec, request, response, base_url=base_url - ) diff --git a/openapi_core/unmarshalling/response/unmarshallers.py b/openapi_core/unmarshalling/response/unmarshallers.py index 0c010c3a..9ff1d54b 100644 --- a/openapi_core/unmarshalling/response/unmarshallers.py +++ b/openapi_core/unmarshalling/response/unmarshallers.py @@ -1,7 +1,3 @@ -from typing import Any -from typing import Mapping - -from openapi_core.protocols import BaseRequest from openapi_core.protocols import Request from openapi_core.protocols import Response from openapi_core.protocols import WebhookRequest @@ -11,18 +7,12 @@ from openapi_core.unmarshalling.response.datatypes import ( ResponseUnmarshalResult, ) -from openapi_core.unmarshalling.response.proxies import ( - SpecResponseValidatorProxy, -) from openapi_core.unmarshalling.schemas import ( oas30_read_schema_unmarshallers_factory, ) from openapi_core.unmarshalling.schemas import ( oas31_schema_unmarshallers_factory, ) -from openapi_core.unmarshalling.schemas.factories import ( - SchemaUnmarshallersFactory, -) from openapi_core.unmarshalling.unmarshallers import BaseUnmarshaller from openapi_core.util import chainiters from openapi_core.validation.response.exceptions import DataValidationError @@ -309,20 +299,3 @@ class V31WebhookResponseUnmarshaller( V31WebhookResponseValidator, WebhookResponseUnmarshaller ): schema_unmarshallers_factory = oas31_schema_unmarshallers_factory - - -# backward compatibility -class ResponseValidator(SpecResponseValidatorProxy): - def __init__( - self, - schema_unmarshallers_factory: "SchemaUnmarshallersFactory", - **kwargs: Any, - ): - super().__init__( - APICallResponseUnmarshaller, - schema_validators_factory=( - schema_unmarshallers_factory.schema_validators_factory - ), - schema_unmarshallers_factory=schema_unmarshallers_factory, - **kwargs, - ) diff --git a/openapi_core/unmarshalling/schemas/factories.py b/openapi_core/unmarshalling/schemas/factories.py index fbf362ba..01bf73e2 100644 --- a/openapi_core/unmarshalling/schemas/factories.py +++ b/openapi_core/unmarshalling/schemas/factories.py @@ -14,7 +14,6 @@ ) from openapi_core.unmarshalling.schemas.unmarshallers import SchemaUnmarshaller from openapi_core.unmarshalling.schemas.unmarshallers import TypesUnmarshaller -from openapi_core.validation.schemas.datatypes import CustomFormattersDict from openapi_core.validation.schemas.datatypes import FormatValidatorsDict from openapi_core.validation.schemas.factories import SchemaValidatorsFactory @@ -25,23 +24,12 @@ def __init__( schema_validators_factory: SchemaValidatorsFactory, types_unmarshaller: TypesUnmarshaller, format_unmarshallers: Optional[FormatUnmarshallersDict] = None, - custom_formatters: Optional[CustomFormattersDict] = None, ): self.schema_validators_factory = schema_validators_factory self.types_unmarshaller = types_unmarshaller if format_unmarshallers is None: format_unmarshallers = {} self.format_unmarshallers = format_unmarshallers - if custom_formatters is None: - custom_formatters = {} - else: - warnings.warn( - "custom_formatters is deprecated. " - "Use extra_format_validators to validate custom formats " - "and use extra_format_unmarshallers to unmarshal custom formats.", - DeprecationWarning, - ) - self.custom_formatters = custom_formatters def create( self, @@ -60,12 +48,6 @@ def create( if extra_format_validators is None: extra_format_validators = {} - extra_format_validators.update( - { - name: formatter.validate - for name, formatter in self.custom_formatters.items() - } - ) schema_validator = self.schema_validators_factory.create( schema, format_validators=format_validators, @@ -77,7 +59,6 @@ def create( formats_unmarshaller = FormatsUnmarshaller( format_unmarshallers or self.format_unmarshallers, extra_format_unmarshallers, - self.custom_formatters, ) # FIXME: don;t raise exception on unknown format diff --git a/openapi_core/unmarshalling/schemas/unmarshallers.py b/openapi_core/unmarshalling/schemas/unmarshallers.py index 27c63179..39617f51 100644 --- a/openapi_core/unmarshalling/schemas/unmarshallers.py +++ b/openapi_core/unmarshalling/schemas/unmarshallers.py @@ -1,5 +1,4 @@ import logging -import warnings from typing import Any from typing import Iterable from typing import Iterator @@ -18,7 +17,6 @@ ) from openapi_core.unmarshalling.schemas.exceptions import FormatUnmarshalError from openapi_core.unmarshalling.schemas.exceptions import UnmarshallerError -from openapi_core.validation.schemas.datatypes import CustomFormattersDict from openapi_core.validation.schemas.validators import SchemaValidator log = logging.getLogger(__name__) @@ -210,7 +208,6 @@ def __init__( self, format_unmarshallers: Optional[FormatUnmarshallersDict] = None, extra_format_unmarshallers: Optional[FormatUnmarshallersDict] = None, - custom_formatters: Optional[CustomFormattersDict] = None, ): if format_unmarshallers is None: format_unmarshallers = {} @@ -218,9 +215,6 @@ def __init__( if extra_format_unmarshallers is None: extra_format_unmarshallers = {} self.extra_format_unmarshallers = extra_format_unmarshallers - if custom_formatters is None: - custom_formatters = {} - self.custom_formatters = custom_formatters def unmarshal(self, schema_format: str, value: Any) -> Any: format_unmarshaller = self.get_unmarshaller(schema_format) @@ -234,9 +228,6 @@ def unmarshal(self, schema_format: str, value: Any) -> Any: def get_unmarshaller( self, schema_format: str ) -> Optional[FormatUnmarshaller]: - if schema_format in self.custom_formatters: - formatter = self.custom_formatters[schema_format] - return formatter.format if schema_format in self.extra_format_unmarshallers: return self.extra_format_unmarshallers[schema_format] if schema_format in self.format_unmarshallers: @@ -246,7 +237,6 @@ def get_unmarshaller( def __contains__(self, schema_format: str) -> bool: format_unmarshallers_dicts: List[Mapping[str, Any]] = [ - self.custom_formatters, self.extra_format_unmarshallers, self.format_unmarshallers, ] @@ -270,14 +260,6 @@ def __init__( self.types_unmarshaller = types_unmarshaller self.formats_unmarshaller = formats_unmarshaller - def __call__(self, value: Any) -> Any: - warnings.warn( - "Calling unmarshaller itself is deprecated. " - "Use unmarshal method instead.", - DeprecationWarning, - ) - return self.unmarshal(value) - def unmarshal(self, value: Any) -> Any: self.schema_validator.validate(value) diff --git a/openapi_core/validation/processors.py b/openapi_core/validation/processors.py index 860b7006..15f0c1b7 100644 --- a/openapi_core/validation/processors.py +++ b/openapi_core/validation/processors.py @@ -1,34 +1,33 @@ """OpenAPI core validation processors module""" +from typing import Optional + from openapi_core.protocols import Request from openapi_core.protocols import Response +from openapi_core.shortcuts import get_classes from openapi_core.spec import Spec -from openapi_core.unmarshalling.request.datatypes import RequestUnmarshalResult -from openapi_core.unmarshalling.request.proxies import ( - SpecRequestValidatorProxy, -) -from openapi_core.unmarshalling.response.datatypes import ( - ResponseUnmarshalResult, -) -from openapi_core.unmarshalling.response.proxies import ( - SpecResponseValidatorProxy, -) +from openapi_core.validation.request.types import RequestValidatorType +from openapi_core.validation.response.types import ResponseValidatorType -class OpenAPISpecProcessor: +class ValidationProcessor: def __init__( self, - request_unmarshaller: SpecRequestValidatorProxy, - response_unmarshaller: SpecResponseValidatorProxy, + spec: Spec, + request_validator_cls: Optional[RequestValidatorType] = None, + response_validator_cls: Optional[ResponseValidatorType] = None, ): - self.request_unmarshaller = request_unmarshaller - self.response_unmarshaller = response_unmarshaller + self.spec = spec + if request_validator_cls is None or response_validator_cls is None: + classes = get_classes(self.spec) + if request_validator_cls is None: + request_validator_cls = classes.request_validator_cls + if response_validator_cls is None: + response_validator_cls = classes.response_validator_cls + self.request_validator = request_validator_cls(self.spec) + self.response_validator = response_validator_cls(self.spec) - def process_request( - self, spec: Spec, request: Request - ) -> RequestUnmarshalResult: - return self.request_unmarshaller.validate(spec, request) + def process_request(self, request: Request) -> None: + self.request_validator.validate(request) - def process_response( - self, spec: Spec, request: Request, response: Response - ) -> ResponseUnmarshalResult: - return self.response_unmarshaller.validate(spec, request, response) + def process_response(self, request: Request, response: Response) -> None: + self.response_validator.validate(request, response) diff --git a/openapi_core/validation/request/exceptions.py b/openapi_core/validation/request/exceptions.py index 9e748642..6d5d3f66 100644 --- a/openapi_core/validation/request/exceptions.py +++ b/openapi_core/validation/request/exceptions.py @@ -1,4 +1,3 @@ -import warnings from dataclasses import dataclass from typing import Iterable @@ -14,15 +13,6 @@ class ParametersError(Exception): parameters: Parameters errors: Iterable[OpenAPIError] - @property - def context(self) -> Iterable[OpenAPIError]: - warnings.warn( - "context property of ParametersError is deprecated. " - "Use errors instead.", - DeprecationWarning, - ) - return self.errors - class RequestValidationError(ValidationError): """Request validation error""" diff --git a/openapi_core/validation/schemas/datatypes.py b/openapi_core/validation/schemas/datatypes.py index 89e9c737..9cec4b7d 100644 --- a/openapi_core/validation/schemas/datatypes.py +++ b/openapi_core/validation/schemas/datatypes.py @@ -1,12 +1,7 @@ from typing import Any from typing import Callable from typing import Dict -from typing import Optional - -from openapi_core.validation.schemas.formatters import Formatter FormatValidator = Callable[[Any], bool] -CustomFormattersDict = Dict[str, Formatter] -FormattersDict = Dict[Optional[str], Formatter] FormatValidatorsDict = Dict[str, FormatValidator] diff --git a/openapi_core/validation/schemas/factories.py b/openapi_core/validation/schemas/factories.py index ce4717df..fe7f4df5 100644 --- a/openapi_core/validation/schemas/factories.py +++ b/openapi_core/validation/schemas/factories.py @@ -7,7 +7,6 @@ from jsonschema.protocols import Validator from openapi_core.spec import Spec -from openapi_core.validation.schemas.datatypes import CustomFormattersDict from openapi_core.validation.schemas.datatypes import FormatValidatorsDict from openapi_core.validation.schemas.validators import SchemaValidator diff --git a/openapi_core/validation/schemas/formatters.py b/openapi_core/validation/schemas/formatters.py deleted file mode 100644 index b0a398f8..00000000 --- a/openapi_core/validation/schemas/formatters.py +++ /dev/null @@ -1,57 +0,0 @@ -import warnings -from typing import Any -from typing import Callable -from typing import Optional -from typing import Type - - -class Formatter: - def validate(self, value: Any) -> bool: - return True - - def format(self, value: Any) -> Any: - return value - - def __getattribute__(self, name: str) -> Any: - if name == "unmarshal": - warnings.warn( - "Unmarshal method is deprecated. " "Use format instead.", - DeprecationWarning, - ) - return super().__getattribute__("format") - if name == "format": - try: - attr = super().__getattribute__("unmarshal") - except AttributeError: - return super().__getattribute__("format") - else: - warnings.warn( - "Unmarshal method is deprecated. " - "Rename unmarshal method to format instead.", - DeprecationWarning, - ) - return attr - return super().__getattribute__(name) - - @classmethod - def from_callables( - cls, - validate_callable: Optional[Callable[[Any], Any]] = None, - format_callable: Optional[Callable[[Any], Any]] = None, - unmarshal: Optional[Callable[[Any], Any]] = None, - ) -> "Formatter": - attrs = {} - if validate_callable is not None: - attrs["validate"] = staticmethod(validate_callable) - if format_callable is not None: - attrs["format"] = staticmethod(format_callable) - if unmarshal is not None: - warnings.warn( - "Unmarshal parameter is deprecated. " - "Use format_callable instead.", - DeprecationWarning, - ) - attrs["format"] = staticmethod(unmarshal) - - klass: Type[Formatter] = type("Formatter", (cls,), attrs) - return klass() diff --git a/poetry.lock b/poetry.lock index 6aff4bc1..ab7025e9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1383,6 +1383,7 @@ description = "parse() is the opposite of format()" optional = false python-versions = "*" files = [ + {file = "parse-1.19.0-py2.py3-none-any.whl", hash = "sha256:6ce007645384a91150cb7cd7c8a9db2559e273c2e2542b508cd1e342508c2601"}, {file = "parse-1.19.0.tar.gz", hash = "sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b"}, ] @@ -2278,4 +2279,4 @@ starlette = ["starlette"] [metadata] lock-version = "2.0" python-versions = "^3.8.0" -content-hash = "f959eda0ef4723b8752d707f50b0ce9ffaf6645cb79d52cf38dbca490f64e9e7" +content-hash = "3cf75354785598f6c6c2c8358456c77a686478ceff952f9437a81f9c10ea4764" diff --git a/pyproject.toml b/pyproject.toml index 4ec00c45..0e85746e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,7 +75,6 @@ jsonschema-spec = "^0.2.2" asgiref = "^3.6.0" jsonschema = {version = "^4.18.0a1", allow-prereleases = true} multidict = {version = "^6.0.4", optional = true} -lazy-object-proxy = "^1.7.1" [tool.poetry.extras] django = ["django"] diff --git a/tests/integration/contrib/aiohttp/conftest.py b/tests/integration/contrib/aiohttp/conftest.py index c5e329e5..a76607a3 100644 --- a/tests/integration/contrib/aiohttp/conftest.py +++ b/tests/integration/contrib/aiohttp/conftest.py @@ -7,8 +7,8 @@ from aiohttp import web from aiohttp.test_utils import TestClient -from openapi_core import openapi_request_validator -from openapi_core import openapi_response_validator +from openapi_core import V30RequestUnmarshaller +from openapi_core import V30ResponseUnmarshaller from openapi_core.contrib.aiohttp import AIOHTTPOpenAPIWebRequest from openapi_core.contrib.aiohttp import AIOHTTPOpenAPIWebResponse @@ -45,7 +45,8 @@ def request_validation(spec, response_getter): async def test_route(request: web.Request) -> web.Response: request_body = await request.text() openapi_request = AIOHTTPOpenAPIWebRequest(request, body=request_body) - result = openapi_request_validator.validate(spec, openapi_request) + unmarshaller = V30RequestUnmarshaller(spec) + result = unmarshaller.unmarshal(openapi_request) response: dict[str, Any] = response_getter() status = 200 if result.errors: @@ -72,9 +73,8 @@ async def test_route(request: web.Request) -> web.Response: status=200, ) openapi_response = AIOHTTPOpenAPIWebResponse(response) - result = openapi_response_validator.validate( - spec, openapi_request, openapi_response - ) + unmarshaller = V30ResponseUnmarshaller(spec) + result = unmarshaller.unmarshal(openapi_request, openapi_response) if result.errors: response = web.json_response( {"errors": [{"message": str(e) for e in result.errors}]}, diff --git a/tests/integration/contrib/starlette/test_starlette_validation.py b/tests/integration/contrib/starlette/test_starlette_validation.py index 895b6ef4..fe147dfc 100644 --- a/tests/integration/contrib/starlette/test_starlette_validation.py +++ b/tests/integration/contrib/starlette/test_starlette_validation.py @@ -8,8 +8,8 @@ from starlette.routing import Route from starlette.testclient import TestClient -from openapi_core import openapi_request_validator -from openapi_core import openapi_response_validator +from openapi_core import unmarshal_request +from openapi_core import unmarshal_response from openapi_core.contrib.starlette import StarletteOpenAPIRequest from openapi_core.contrib.starlette import StarletteOpenAPIResponse @@ -50,7 +50,7 @@ def test_request_validator_path_pattern(self, client, spec): def test_route(request): openapi_request = StarletteOpenAPIRequest(request) - result = openapi_request_validator.validate(spec, openapi_request) + result = unmarshal_request(openapi_request, spec) assert not result.errors return JSONResponse( response_data, @@ -92,8 +92,8 @@ def test_route(request): ) openapi_request = StarletteOpenAPIRequest(request) openapi_response = StarletteOpenAPIResponse(response) - result = openapi_response_validator.validate( - spec, openapi_request, openapi_response + result = unmarshal_response( + openapi_request, openapi_response, spec ) assert not result.errors return response diff --git a/tests/integration/schema/test_spec.py b/tests/integration/schema/test_spec.py index d4026869..a0d447c5 100644 --- a/tests/integration/schema/test_spec.py +++ b/tests/integration/schema/test_spec.py @@ -4,9 +4,9 @@ from openapi_spec_validator import openapi_v30_spec_validator from openapi_spec_validator import openapi_v31_spec_validator -from openapi_core import RequestValidator -from openapi_core import ResponseValidator from openapi_core import Spec +from openapi_core import V30RequestValidator +from openapi_core import V30ResponseValidator from openapi_core.schema.servers import get_server_url from openapi_core.schema.specs import get_spec_url @@ -37,11 +37,11 @@ def spec(self, spec_dict, base_uri): @pytest.fixture def request_validator(self, spec): - return RequestValidator(spec) + return V30RequestValidator(spec) @pytest.fixture def response_validator(self, spec): - return ResponseValidator(spec) + return V30ResponseValidator(spec) def test_spec(self, spec, spec_dict): url = "http://petstore.swagger.io/v1" diff --git a/tests/integration/test_minimal.py b/tests/integration/test_minimal.py index 3fd06cd7..6575e06a 100644 --- a/tests/integration/test_minimal.py +++ b/tests/integration/test_minimal.py @@ -1,5 +1,6 @@ import pytest +from openapi_core import unmarshal_request from openapi_core import validate_request from openapi_core.templating.paths.exceptions import OperationNotFound from openapi_core.templating.paths.exceptions import PathNotFound @@ -28,7 +29,7 @@ def test_hosts(self, factory, server, spec_path): spec = factory.spec_from_file(spec_path) request = MockRequest(server, "get", "/status") - result = validate_request(request, spec=spec) + result = unmarshal_request(request, spec=spec) assert not result.errors diff --git a/tests/integration/unmarshalling/test_unmarshallers.py b/tests/integration/unmarshalling/test_unmarshallers.py index 3e3eb004..6fa0708d 100644 --- a/tests/integration/unmarshalling/test_unmarshallers.py +++ b/tests/integration/unmarshalling/test_unmarshallers.py @@ -52,28 +52,6 @@ def test_create_formatter_not_found(self, unmarshallers_factory): ): unmarshallers_factory.create(spec) - @pytest.mark.parametrize( - "value", - [ - "test", - 10, - 10, - 3.12, - ["one", "two"], - True, - False, - ], - ) - def test_call_deprecated(self, unmarshallers_factory, value): - schema = {} - spec = Spec.from_dict(schema, validator=None) - unmarshaller = unmarshallers_factory.create(spec) - - with pytest.warns(DeprecationWarning): - result = unmarshaller(value) - - assert result == value - @pytest.mark.parametrize( "value", [ diff --git a/tests/unit/deserializing/test_media_types_deserializers.py b/tests/unit/deserializing/test_media_types_deserializers.py index 40960651..528996e5 100644 --- a/tests/unit/deserializing/test_media_types_deserializers.py +++ b/tests/unit/deserializing/test_media_types_deserializers.py @@ -14,11 +14,9 @@ def create_deserializer( media_type, media_type_deserializers=media_type_deserializers, extra_media_type_deserializers=None, - custom_deserializers=None, ): return MediaTypeDeserializersFactory( media_type_deserializers, - custom_deserializers=custom_deserializers, ).create( media_type, extra_media_type_deserializers=extra_media_type_deserializers, @@ -109,26 +107,6 @@ def test_data_form_simple(self, deserializer_factory): assert result == {"param1": b"test"} - def test_custom_deserializer(self, deserializer_factory): - deserialized = "x-custom" - - def custom_deserializer(value): - return deserialized - - custom_mimetype = "application/custom" - custom_deserializers = { - custom_mimetype: custom_deserializer, - } - with pytest.warns(DeprecationWarning): - deserializer = deserializer_factory( - custom_mimetype, custom_deserializers=custom_deserializers - ) - value = "{}" - - result = deserializer.deserialize(value) - - assert result == deserialized - def test_custom_simple(self, deserializer_factory): deserialized = "x-custom" diff --git a/tests/unit/test_shortcuts.py b/tests/unit/test_shortcuts.py index b64fdac5..f5fe9c02 100644 --- a/tests/unit/test_shortcuts.py +++ b/tests/unit/test_shortcuts.py @@ -2,8 +2,6 @@ import pytest -from openapi_core import RequestValidator -from openapi_core import ResponseValidator from openapi_core import unmarshal_apicall_request from openapi_core import unmarshal_apicall_response from openapi_core import unmarshal_request @@ -182,6 +180,40 @@ def test_spec_type_invalid(self): with pytest.raises(TypeError): unmarshal_request(request, spec=spec) + def test_cls_apicall_unmarshaller(self, spec_v31): + request = mock.Mock(spec=Request) + unmarshal = mock.Mock(spec=RequestUnmarshalResult) + TestAPICallReq = type( + "TestAPICallReq", + (MockReqUnmarshaller, APICallRequestUnmarshaller), + {}, + ) + TestAPICallReq.setUp(unmarshal) + + result = unmarshal_request(request, spec=spec_v31, cls=TestAPICallReq) + + assert result == unmarshal + assert TestAPICallReq.unmarshal_calls == [ + (request,), + ] + + def test_cls_webhook_unmarshaller(self, spec_v31): + request = mock.Mock(spec=WebhookRequest) + unmarshal = mock.Mock(spec=RequestUnmarshalResult) + TestWebhookReq = type( + "TestWebhookReq", + (MockReqUnmarshaller, WebhookRequestUnmarshaller), + {}, + ) + TestWebhookReq.setUp(unmarshal) + + result = unmarshal_request(request, spec=spec_v31, cls=TestWebhookReq) + + assert result == unmarshal + assert TestWebhookReq.unmarshal_calls == [ + (request,), + ] + @pytest.mark.parametrize("req", [Request, WebhookRequest]) def test_cls_type_invalid(self, spec_v31, req): request = mock.Mock(spec=req) @@ -201,6 +233,19 @@ def test_request(self, mock_unmarshal, spec_v31): assert result == mock_unmarshal.return_value mock_unmarshal.assert_called_once_with(request) + @mock.patch( + "openapi_core.unmarshalling.request.unmarshallers.APICallRequestUnmarshaller." + "unmarshal", + ) + def test_request_error(self, mock_unmarshal, spec_v31): + request = mock.Mock(spec=Request) + mock_unmarshal.return_value = ResultMock(error_to_raise=ValueError) + + with pytest.raises(ValueError): + unmarshal_request(request, spec=spec_v31) + + mock_unmarshal.assert_called_once_with(request) + class TestUnmarshalAPICallResponse: def test_spec_not_detected(self, spec_invalid): @@ -272,6 +317,46 @@ def test_spec_type_invalid(self): with pytest.raises(TypeError): unmarshal_response(request, response, spec=spec) + def test_cls_apicall_unmarshaller(self, spec_v31): + request = mock.Mock(spec=Request) + response = mock.Mock(spec=Response) + unmarshal = mock.Mock(spec=ResponseUnmarshalResult) + TestAPICallReq = type( + "TestAPICallReq", + (MockRespUnmarshaller, APICallResponseUnmarshaller), + {}, + ) + TestAPICallReq.setUp(unmarshal) + + result = unmarshal_response( + request, response, spec=spec_v31, cls=TestAPICallReq + ) + + assert result == unmarshal + assert TestAPICallReq.unmarshal_calls == [ + (request, response), + ] + + def test_cls_webhook_unmarshaller(self, spec_v31): + request = mock.Mock(spec=WebhookRequest) + response = mock.Mock(spec=Response) + unmarshal = mock.Mock(spec=ResponseUnmarshalResult) + TestWebhookReq = type( + "TestWebhookReq", + (MockRespUnmarshaller, WebhookResponseUnmarshaller), + {}, + ) + TestWebhookReq.setUp(unmarshal) + + result = unmarshal_response( + request, response, spec=spec_v31, cls=TestWebhookReq + ) + + assert result == unmarshal + assert TestWebhookReq.unmarshal_calls == [ + (request, response), + ] + @pytest.mark.parametrize("req", [Request, WebhookRequest]) def test_cls_type_invalid(self, spec_v31, req): request = mock.Mock(spec=req) @@ -293,6 +378,21 @@ def test_request_response(self, mock_unmarshal, spec_v31): assert result == mock_unmarshal.return_value mock_unmarshal.assert_called_once_with(request, response) + @mock.patch( + "openapi_core.unmarshalling.response.unmarshallers.APICallResponseUnmarshaller." + "unmarshal", + ) + def test_request_response_error(self, mock_unmarshal, spec_v31): + request = mock.Mock(spec=Request) + response = mock.Mock(spec=Response) + mock_unmarshal.return_value = ResultMock(error_to_raise=ValueError) + + with pytest.raises(ValueError): + with pytest.warns(DeprecationWarning): + unmarshal_response(request, response, spec=spec_v31) + + mock_unmarshal.assert_called_once_with(request, response) + class TestUnmarshalWebhookResponse: def test_spec_not_detected(self, spec_invalid): @@ -460,58 +560,16 @@ def test_spec_type_invalid(self): validate_request(request, spec=spec) @mock.patch( - "openapi_core.unmarshalling.request.unmarshallers.APICallRequestUnmarshaller." - "unmarshal", - ) - def test_request(self, mock_unmarshal, spec_v31): - request = mock.Mock(spec=Request) - - result = validate_request(request, spec=spec_v31) - - with pytest.warns(DeprecationWarning): - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request) - - @mock.patch( - "openapi_core.unmarshalling.request.unmarshallers.APICallRequestUnmarshaller." - "unmarshal", - ) - def test_spec_as_first_arg_deprecated(self, mock_unmarshal, spec_v31): - request = mock.Mock(spec=Request) - - with pytest.warns(DeprecationWarning): - result = validate_request(spec_v31, request) - - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request) - - @mock.patch( - "openapi_core.unmarshalling.request.unmarshallers.APICallRequestUnmarshaller." - "unmarshal", + "openapi_core.validation.request.validators.APICallRequestValidator." + "validate", ) - def test_request_error(self, mock_unmarshal, spec_v31): - request = mock.Mock(spec=Request) - mock_unmarshal.return_value = ResultMock(error_to_raise=ValueError) - - with pytest.raises(ValueError): - with pytest.warns(DeprecationWarning): - validate_request(request, spec=spec_v31) - - mock_unmarshal.assert_called_once_with(request) - - def test_validator(self, spec_v31): + def test_request(self, mock_validate, spec_v31): request = mock.Mock(spec=Request) - validator = mock.Mock(spec=RequestValidator) + mock_validate.return_value = None - with pytest.warns(DeprecationWarning): - result = validate_request( - request, spec=spec_v31, validator=validator - ) + validate_request(request, spec=spec_v31) - assert result == validator.validate.return_value - validator.validate.assert_called_once_with( - spec_v31, request, base_url=None - ) + mock_validate.assert_called_once_with(request) def test_cls_apicall(self, spec_v31): request = mock.Mock(spec=Request) @@ -528,24 +586,6 @@ def test_cls_apicall(self, spec_v31): (request,), ] - def test_cls_apicall_unmarshaller(self, spec_v31): - request = mock.Mock(spec=Request) - unmarshal = mock.Mock(spec=RequestUnmarshalResult) - TestAPICallReq = type( - "TestAPICallReq", - (MockReqUnmarshaller, APICallRequestUnmarshaller), - {}, - ) - TestAPICallReq.setUp(unmarshal) - - result = validate_request(request, spec=spec_v31, cls=TestAPICallReq) - - with pytest.warns(DeprecationWarning): - assert result == unmarshal - assert TestAPICallReq.unmarshal_calls == [ - (request,), - ] - def test_cls_webhook(self, spec_v31): request = mock.Mock(spec=Request) TestWebhookReq = type( @@ -576,24 +616,6 @@ def test_webhook_cls(self, spec_v31): (request,), ] - def test_cls_webhook_unmarshaller(self, spec_v31): - request = mock.Mock(spec=WebhookRequest) - unmarshal = mock.Mock(spec=RequestUnmarshalResult) - TestWebhookReq = type( - "TestWebhookReq", - (MockReqUnmarshaller, WebhookRequestUnmarshaller), - {}, - ) - TestWebhookReq.setUp(unmarshal) - - result = validate_request(request, spec=spec_v31, cls=TestWebhookReq) - - with pytest.warns(DeprecationWarning): - assert result == unmarshal - assert TestWebhookReq.unmarshal_calls == [ - (request,), - ] - def test_cls_invalid(self, spec_v31): request = mock.Mock(spec=Request) @@ -601,17 +623,16 @@ def test_cls_invalid(self, spec_v31): validate_request(request, spec=spec_v31, cls=Exception) @mock.patch( - "openapi_core.unmarshalling.request.unmarshallers.WebhookRequestUnmarshaller." - "unmarshal", + "openapi_core.validation.request.validators.V31WebhookRequestValidator." + "validate", ) - def test_webhook_request(self, mock_unmarshal, spec_v31): + def test_webhook_request(self, mock_validate, spec_v31): request = mock.Mock(spec=WebhookRequest) + mock_validate.return_value = None - result = validate_request(request, spec=spec_v31) + validate_request(request, spec=spec_v31) - with pytest.warns(DeprecationWarning): - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request) + mock_validate.assert_called_once_with(request) def test_webhook_request_validator_not_found(self, spec_v30): request = mock.Mock(spec=WebhookRequest) @@ -621,18 +642,17 @@ def test_webhook_request_validator_not_found(self, spec_v30): validate_request(request, spec=spec_v30) @mock.patch( - "openapi_core.unmarshalling.request.unmarshallers.WebhookRequestUnmarshaller." - "unmarshal", + "openapi_core.validation.request.validators.V31WebhookRequestValidator." + "validate", ) - def test_webhook_request_error(self, mock_unmarshal, spec_v31): + def test_webhook_request_error(self, mock_validate, spec_v31): request = mock.Mock(spec=WebhookRequest) - mock_unmarshal.return_value = ResultMock(error_to_raise=ValueError) + mock_validate.side_effect = ValueError with pytest.raises(ValueError): - with pytest.warns(DeprecationWarning): - validate_request(request, spec=spec_v31) + validate_request(request, spec=spec_v31) - mock_unmarshal.assert_called_once_with(request) + mock_validate.assert_called_once_with(request) def test_webhook_cls_invalid(self, spec_v31): request = mock.Mock(spec=WebhookRequest) @@ -786,62 +806,17 @@ def test_spec_type_invalid(self): validate_response(request, response, spec=spec) @mock.patch( - "openapi_core.unmarshalling.response.unmarshallers.APICallResponseUnmarshaller." - "unmarshal", - ) - def test_request_response(self, mock_unmarshal, spec_v31): - request = mock.Mock(spec=Request) - response = mock.Mock(spec=Response) - - result = validate_response(request, response, spec=spec_v31) - - with pytest.warns(DeprecationWarning): - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request, response) - - @mock.patch( - "openapi_core.unmarshalling.response.unmarshallers.APICallResponseUnmarshaller." - "unmarshal", - ) - def test_spec_as_first_arg_deprecated(self, mock_unmarshal, spec_v31): - request = mock.Mock(spec=Request) - response = mock.Mock(spec=Response) - - with pytest.warns(DeprecationWarning): - result = validate_response(spec_v31, request, response) - - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request, response) - - @mock.patch( - "openapi_core.unmarshalling.response.unmarshallers.APICallResponseUnmarshaller." - "unmarshal", + "openapi_core.validation.response.validators.APICallResponseValidator." + "validate", ) - def test_request_response_error(self, mock_unmarshal, spec_v31): - request = mock.Mock(spec=Request) - response = mock.Mock(spec=Response) - mock_unmarshal.return_value = ResultMock(error_to_raise=ValueError) - - with pytest.raises(ValueError): - with pytest.warns(DeprecationWarning): - validate_response(request, response, spec=spec_v31) - - mock_unmarshal.assert_called_once_with(request, response) - - def test_validator(self, spec_v31): + def test_request_response(self, mock_validate, spec_v31): request = mock.Mock(spec=Request) response = mock.Mock(spec=Response) - validator = mock.Mock(spec=ResponseValidator) + mock_validate.return_value = None - with pytest.warns(DeprecationWarning): - result = validate_response( - request, response, spec=spec_v31, validator=validator - ) + validate_response(request, response, spec=spec_v31) - assert result == validator.validate.return_value - validator.validate.assert_called_once_with( - spec_v31, request, response, base_url=None - ) + mock_validate.assert_called_once_with(request, response) def test_cls_apicall(self, spec_v31): request = mock.Mock(spec=Request) @@ -861,48 +836,6 @@ def test_cls_apicall(self, spec_v31): (request, response), ] - def test_cls_apicall_unmarshaller(self, spec_v31): - request = mock.Mock(spec=Request) - response = mock.Mock(spec=Response) - unmarshal = mock.Mock(spec=ResponseUnmarshalResult) - TestAPICallReq = type( - "TestAPICallReq", - (MockRespUnmarshaller, APICallResponseUnmarshaller), - {}, - ) - TestAPICallReq.setUp(unmarshal) - - result = validate_response( - request, response, spec=spec_v31, cls=TestAPICallReq - ) - - with pytest.warns(DeprecationWarning): - assert result == unmarshal - assert TestAPICallReq.unmarshal_calls == [ - (request, response), - ] - - def test_cls_webhook_unmarshaller(self, spec_v31): - request = mock.Mock(spec=WebhookRequest) - response = mock.Mock(spec=Response) - unmarshal = mock.Mock(spec=ResponseUnmarshalResult) - TestWebhookReq = type( - "TestWebhookReq", - (MockRespUnmarshaller, WebhookResponseUnmarshaller), - {}, - ) - TestWebhookReq.setUp(unmarshal) - - result = validate_response( - request, response, spec=spec_v31, cls=TestWebhookReq - ) - - with pytest.warns(DeprecationWarning): - assert result == unmarshal - assert TestWebhookReq.unmarshal_calls == [ - (request, response), - ] - def test_cls_type_invalid(self, spec_v31): request = mock.Mock(spec=Request) response = mock.Mock(spec=Response) @@ -919,33 +852,31 @@ def test_webhook_response_validator_not_found(self, spec_v30): validate_response(request, response, spec=spec_v30) @mock.patch( - "openapi_core.unmarshalling.response.unmarshallers.WebhookResponseUnmarshaller." - "unmarshal", + "openapi_core.validation.response.validators.V31WebhookResponseValidator." + "validate", ) - def test_webhook_request(self, mock_unmarshal, spec_v31): + def test_webhook_request(self, mock_validate, spec_v31): request = mock.Mock(spec=WebhookRequest) response = mock.Mock(spec=Response) + mock_validate.return_value = None - result = validate_response(request, response, spec=spec_v31) + validate_response(request, response, spec=spec_v31) - with pytest.warns(DeprecationWarning): - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request, response) + mock_validate.assert_called_once_with(request, response) @mock.patch( - "openapi_core.unmarshalling.response.unmarshallers.WebhookResponseUnmarshaller." - "unmarshal", + "openapi_core.validation.response.validators.V31WebhookResponseValidator." + "validate", ) - def test_webhook_request_error(self, mock_unmarshal, spec_v31): + def test_webhook_request_error(self, mock_validate, spec_v31): request = mock.Mock(spec=WebhookRequest) response = mock.Mock(spec=Response) - mock_unmarshal.return_value = ResultMock(error_to_raise=ValueError) + mock_validate.side_effect = ValueError with pytest.raises(ValueError): - with pytest.warns(DeprecationWarning): - validate_response(request, response, spec=spec_v31) + validate_response(request, response, spec=spec_v31) - mock_unmarshal.assert_called_once_with(request, response) + mock_validate.assert_called_once_with(request, response) def test_webhook_cls(self, spec_v31): request = mock.Mock(spec=WebhookRequest) diff --git a/tests/unit/unmarshalling/test_path_item_params_validator.py b/tests/unit/unmarshalling/test_path_item_params_validator.py index 4dc17ddf..21695421 100644 --- a/tests/unit/unmarshalling/test_path_item_params_validator.py +++ b/tests/unit/unmarshalling/test_path_item_params_validator.py @@ -4,7 +4,8 @@ from openapi_core import Spec from openapi_core import V30RequestUnmarshaller -from openapi_core import openapi_request_validator +from openapi_core import unmarshal_request +from openapi_core import validate_request from openapi_core.casting.schemas.exceptions import CastError from openapi_core.datatypes import Parameters from openapi_core.testing import MockRequest @@ -105,10 +106,9 @@ def test_request_override_param(self, spec, spec_dict): } ] request = MockRequest("http://example.com", "get", "/resource") - with pytest.warns(DeprecationWarning): - result = openapi_request_validator.validate( - spec, request, base_url="http://example.com" - ) + result = unmarshal_request( + request, spec, base_url="http://example.com" + ) assert len(result.errors) == 0 assert result.body is None @@ -129,15 +129,8 @@ def test_request_override_param_uniqueness(self, spec, spec_dict): } ] request = MockRequest("http://example.com", "get", "/resource") - with pytest.warns(DeprecationWarning): - result = openapi_request_validator.validate( - spec, request, base_url="http://example.com" - ) - - assert len(result.errors) == 1 - assert type(result.errors[0]) == MissingRequiredParameter - assert result.body is None - assert result.parameters == Parameters() + with pytest.raises(MissingRequiredParameter): + validate_request(request, spec, base_url="http://example.com") def test_request_object_deep_object_params(self, spec, spec_dict): # override path parameter on operation @@ -166,10 +159,9 @@ def test_request_object_deep_object_params(self, spec, spec_dict): "/resource", args={"paramObj[count]": 2, "paramObj[name]": "John"}, ) - with pytest.warns(DeprecationWarning): - result = openapi_request_validator.validate( - spec, request, base_url="http://example.com" - ) + result = unmarshal_request( + request, spec, base_url="http://example.com" + ) assert len(result.errors) == 0 assert result.body is None diff --git a/tests/unit/unmarshalling/test_schema_unmarshallers.py b/tests/unit/unmarshalling/test_schema_unmarshallers.py index 45edf956..c25e9005 100644 --- a/tests/unit/unmarshalling/test_schema_unmarshallers.py +++ b/tests/unit/unmarshalling/test_schema_unmarshallers.py @@ -17,7 +17,6 @@ ) from openapi_core.validation.schemas.exceptions import InvalidSchemaValue from openapi_core.validation.schemas.factories import SchemaValidatorsFactory -from openapi_core.validation.schemas.formatters import Formatter @pytest.fixture @@ -28,12 +27,10 @@ def create_unmarshaller( format_validators=None, extra_format_validators=None, extra_format_unmarshallers=None, - custom_formatters=None, ): return SchemaUnmarshallersFactory( validators_factory, oas30_types_unmarshaller, - custom_formatters=custom_formatters, ).create( schema, format_validators=format_validators, @@ -80,110 +77,6 @@ def test_string_format_invalid_value(self, unmarshaller_factory): class TestOAS30SchemaUnmarshallerUnmarshal: - def test_schema_custom_formatter_format_invalid( - self, unmarshaller_factory - ): - class CustomFormatter(Formatter): - def format(self, value): - raise ValueError - - formatter = CustomFormatter() - custom_format = "custom" - custom_formatters = { - custom_format: formatter, - } - schema = { - "type": "string", - "format": "custom", - } - spec = Spec.from_dict(schema, validator=None) - value = "x" - with pytest.warns(DeprecationWarning): - unmarshaller = unmarshaller_factory( - spec, - custom_formatters=custom_formatters, - ) - - with pytest.raises(FormatUnmarshalError): - unmarshaller.unmarshal(value) - - def test_string_format_custom(self, unmarshaller_factory): - formatted = "x-custom" - - class CustomFormatter(Formatter): - def format(self, value): - return formatted - - custom_format = "custom" - schema = { - "type": "string", - "format": custom_format, - } - spec = Spec.from_dict(schema, validator=None) - value = "x" - formatter = CustomFormatter() - custom_formatters = { - custom_format: formatter, - } - with pytest.warns(DeprecationWarning): - unmarshaller = unmarshaller_factory( - spec, custom_formatters=custom_formatters - ) - - result = unmarshaller.unmarshal(value) - - assert result == formatted - - def test_array_format_custom_formatter(self, unmarshaller_factory): - class CustomFormatter(Formatter): - def unmarshal(self, value): - return tuple(value) - - custom_format = "custom" - schema = { - "type": "array", - "format": custom_format, - } - spec = Spec.from_dict(schema, validator=None) - value = ["x"] - formatter = CustomFormatter() - custom_formatters = { - custom_format: formatter, - } - with pytest.warns(DeprecationWarning): - unmarshaller = unmarshaller_factory( - spec, custom_formatters=custom_formatters - ) - - with pytest.warns(DeprecationWarning): - result = unmarshaller.unmarshal(value) - - assert result == tuple(value) - - def test_string_format_custom_value_error(self, unmarshaller_factory): - class CustomFormatter(Formatter): - def format(self, value): - raise ValueError - - custom_format = "custom" - schema = { - "type": "string", - "format": custom_format, - } - spec = Spec.from_dict(schema, validator=None) - value = "x" - formatter = CustomFormatter() - custom_formatters = { - custom_format: formatter, - } - with pytest.warns(DeprecationWarning): - unmarshaller = unmarshaller_factory( - spec, custom_formatters=custom_formatters - ) - - with pytest.raises(FormatUnmarshalError): - unmarshaller.unmarshal(value) - def test_schema_extra_format_unmarshaller_format_invalid( self, schema_unmarshaller_factory, unmarshaller_factory ): diff --git a/tests/unit/validation/test_request_response_validators.py b/tests/unit/validation/test_request_response_validators.py deleted file mode 100644 index 31dd2c9a..00000000 --- a/tests/unit/validation/test_request_response_validators.py +++ /dev/null @@ -1,107 +0,0 @@ -from unittest import mock - -import pytest -from openapi_schema_validator import OAS31Validator - -from openapi_core import RequestValidator -from openapi_core import ResponseValidator -from openapi_core import openapi_request_validator -from openapi_core import openapi_response_validator -from openapi_core.unmarshalling.schemas import oas31_types_unmarshaller -from openapi_core.unmarshalling.schemas.factories import ( - SchemaUnmarshallersFactory, -) -from openapi_core.validation.schemas import oas31_schema_validators_factory -from openapi_core.validation.schemas.formatters import Formatter - - -class BaseTestValidate: - @pytest.fixture - def schema_unmarshallers_factory(self): - CUSTOM_FORMATTERS = {"custom": Formatter.from_callables()} - with pytest.warns(DeprecationWarning): - return SchemaUnmarshallersFactory( - oas31_schema_validators_factory, - oas31_types_unmarshaller, - custom_formatters=CUSTOM_FORMATTERS, - ) - - -class TestRequestValidatorValidate(BaseTestValidate): - @pytest.fixture - def validator(self, schema_unmarshallers_factory): - return RequestValidator(schema_unmarshallers_factory) - - @mock.patch( - "openapi_core.unmarshalling.request.unmarshallers.APICallRequestUnmarshaller." - "unmarshal", - ) - def test_valid(self, mock_unmarshal, validator): - spec = mock.sentinel.spec - request = mock.sentinel.request - - with pytest.warns(DeprecationWarning): - result = validator.validate(spec, request) - - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request) - - -class TestResponseValidatorValidate(BaseTestValidate): - @pytest.fixture - def validator(self, schema_unmarshallers_factory): - return ResponseValidator(schema_unmarshallers_factory) - - @mock.patch( - "openapi_core.unmarshalling.response.unmarshallers.APICallResponseUnmarshaller." - "unmarshal", - ) - def test_valid(self, mock_unmarshal, validator): - spec = mock.sentinel.spec - request = mock.sentinel.request - response = mock.sentinel.response - - with pytest.warns(DeprecationWarning): - result = validator.validate(spec, request, response) - - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request, response) - - -class TestDetectProxyOpenAPIRequestValidator: - @pytest.fixture - def validator(self): - return openapi_request_validator - - @mock.patch( - "openapi_core.unmarshalling.request.unmarshallers.APICallRequestUnmarshaller." - "unmarshal", - ) - def test_valid(self, mock_unmarshal, validator, spec_v31): - request = mock.sentinel.request - - with pytest.warns(DeprecationWarning): - result = validator.validate(spec_v31, request) - - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request) - - -class TestDetectProxyOpenAPIResponsealidator: - @pytest.fixture - def validator(self): - return openapi_response_validator - - @mock.patch( - "openapi_core.unmarshalling.response.unmarshallers.APICallResponseUnmarshaller." - "unmarshal", - ) - def test_valid(self, mock_unmarshal, validator, spec_v31): - request = mock.sentinel.request - response = mock.sentinel.response - - with pytest.warns(DeprecationWarning): - result = validator.validate(spec_v31, request, response) - - assert result == mock_unmarshal.return_value - mock_unmarshal.assert_called_once_with(request, response)