Move media deserializers to separate subpackage

This commit is contained in:
Artur Maciag 2020-02-03 13:34:43 +00:00
parent 58d5c26fee
commit 6d8b2e5111
10 changed files with 93 additions and 93 deletions

View file

@ -0,0 +1,14 @@
from openapi_core.deserializing.exceptions import DeserializeError
class PrimitiveDeserializer(object):
def __init__(self, mimetype, deserializer_callable):
self.mimetype = mimetype
self.deserializer_callable = deserializer_callable
def __call__(self, value):
try:
return self.deserializer_callable(value)
except (ValueError, TypeError, AttributeError) as exc:
raise DeserializeError(value, self.mimetype)

View file

@ -0,0 +1,18 @@
from openapi_core.schema.media_types.util import json_loads
from openapi_core.deserializing.media_types.deserializers import (
PrimitiveDeserializer,
)
class MediaTypeDeserializersFactory(object):
MEDIA_TYPE_DESERIALIZERS = {
'application/json': json_loads,
}
def create(self, media_type):
deserialize_callable = self.MEDIA_TYPE_DESERIALIZERS.get(
media_type.mimetype, lambda x: x)
return PrimitiveDeserializer(
media_type.mimetype, deserialize_callable)

View file

@ -7,14 +7,6 @@ class OpenAPIMediaTypeError(OpenAPIMappingError):
pass pass
@attr.s(hash=True)
class InvalidMediaTypeValue(OpenAPIMediaTypeError):
original_exception = attr.ib()
def __str__(self):
return "Mimetype invalid: {0}".format(self.original_exception)
@attr.s(hash=True) @attr.s(hash=True)
class InvalidContentType(OpenAPIMediaTypeError): class InvalidContentType(OpenAPIMediaTypeError):
mimetype = attr.ib() mimetype = attr.ib()

View file

@ -1,16 +1,4 @@
"""OpenAPI core media types models module""" """OpenAPI core media types models module"""
from collections import defaultdict
from openapi_core.schema.media_types.exceptions import InvalidMediaTypeValue
from openapi_core.schema.media_types.util import json_loads
from openapi_core.casting.schemas.exceptions import CastError
MEDIA_TYPE_DESERIALIZERS = {
'application/json': json_loads,
}
class MediaType(object): class MediaType(object):
"""Represents an OpenAPI MediaType.""" """Represents an OpenAPI MediaType."""
@ -18,30 +6,3 @@ class MediaType(object):
self.mimetype = mimetype self.mimetype = mimetype
self.schema = schema self.schema = schema
self.example = example self.example = example
def get_deserializer_mapping(self):
mapping = MEDIA_TYPE_DESERIALIZERS.copy()
return defaultdict(lambda: lambda x: x, mapping)
def get_dererializer(self):
mapping = self.get_deserializer_mapping()
return mapping[self.mimetype]
def deserialize(self, value):
deserializer = self.get_dererializer()
return deserializer(value)
def deserialise(self, value):
try:
return self.deserialize(value)
except ValueError as exc:
raise InvalidMediaTypeValue(exc)
def cast(self, value):
if not self.schema:
return value
try:
return self.schema.cast(value)
except CastError as exc:
raise InvalidMediaTypeValue(exc)

View file

@ -4,9 +4,7 @@ from six import iteritems
from openapi_core.casting.schemas.exceptions import CastError from openapi_core.casting.schemas.exceptions import CastError
from openapi_core.deserializing.exceptions import DeserializeError from openapi_core.deserializing.exceptions import DeserializeError
from openapi_core.schema.media_types.exceptions import ( from openapi_core.schema.media_types.exceptions import InvalidContentType
InvalidMediaTypeValue, InvalidContentType,
)
from openapi_core.schema.operations.exceptions import InvalidOperation from openapi_core.schema.operations.exceptions import InvalidOperation
from openapi_core.schema.parameters.enums import ParameterLocation from openapi_core.schema.parameters.enums import ParameterLocation
from openapi_core.schema.parameters.exceptions import ( from openapi_core.schema.parameters.exceptions import (
@ -150,7 +148,7 @@ class RequestValidator(object):
try: try:
deserialised = self._deserialise_media_type(media_type, raw_body) deserialised = self._deserialise_media_type(media_type, raw_body)
except InvalidMediaTypeValue as exc: except DeserializeError as exc:
return None, [exc, ] return None, [exc, ]
try: try:
@ -186,8 +184,14 @@ class RequestValidator(object):
raise MissingRequestBody(request) raise MissingRequestBody(request)
return request.body return request.body
def _deserialise_media_type(self, param_or_media_type, value): def _deserialise_media_type(self, media_type, value):
return param_or_media_type.deserialise(value) from openapi_core.deserializing.media_types.factories import (
MediaTypeDeserializersFactory,
)
deserializers_factory = MediaTypeDeserializersFactory()
deserializer = deserializers_factory.create(media_type)
return deserializer(value)
def _deserialise_parameter(self, param, value): def _deserialise_parameter(self, param, value):
from openapi_core.deserializing.parameters.factories import ( from openapi_core.deserializing.parameters.factories import (

View file

@ -1,9 +1,8 @@
"""OpenAPI core validation response validators module""" """OpenAPI core validation response validators module"""
from openapi_core.casting.schemas.exceptions import CastError from openapi_core.casting.schemas.exceptions import CastError
from openapi_core.deserializing.exceptions import DeserializeError
from openapi_core.schema.operations.exceptions import InvalidOperation from openapi_core.schema.operations.exceptions import InvalidOperation
from openapi_core.schema.media_types.exceptions import ( from openapi_core.schema.media_types.exceptions import InvalidContentType
InvalidMediaTypeValue, InvalidContentType,
)
from openapi_core.schema.responses.exceptions import ( from openapi_core.schema.responses.exceptions import (
InvalidResponse, MissingResponseContent, InvalidResponse, MissingResponseContent,
) )
@ -79,8 +78,8 @@ class ResponseValidator(object):
return None, [exc, ] return None, [exc, ]
try: try:
deserialised = self._deserialise(media_type, raw_data) deserialised = self._deserialise_media_type(media_type, raw_data)
except InvalidMediaTypeValue as exc: except DeserializeError as exc:
return None, [exc, ] return None, [exc, ]
try: try:
@ -109,8 +108,13 @@ class ResponseValidator(object):
return response.data return response.data
def _deserialise(self, param_or_media_type, value): def _deserialise_media_type(self, media_type, value):
return param_or_media_type.deserialise(value) from openapi_core.deserializing.media_types.factories import (
MediaTypeDeserializersFactory,
)
deserializers_factory = MediaTypeDeserializersFactory()
deserializer = deserializers_factory.create(media_type)
return deserializer(value)
def _cast(self, param_or_media_type, value): def _cast(self, param_or_media_type, value):
# return param_or_media_type.cast(value) # return param_or_media_type.cast(value)

View file

@ -4,8 +4,9 @@ import pytest
from six import text_type from six import text_type
from openapi_core.casting.schemas.exceptions import CastError from openapi_core.casting.schemas.exceptions import CastError
from openapi_core.deserializing.exceptions import DeserializeError
from openapi_core.schema.media_types.exceptions import ( from openapi_core.schema.media_types.exceptions import (
InvalidContentType, InvalidMediaTypeValue, InvalidContentType,
) )
from openapi_core.extensions.models.models import BaseModel from openapi_core.extensions.models.models import BaseModel
from openapi_core.schema.operations.exceptions import InvalidOperation from openapi_core.schema.operations.exceptions import InvalidOperation
@ -455,7 +456,7 @@ class TestResponseValidator(object):
result = validator.validate(request, response) result = validator.validate(request, response)
assert len(result.errors) == 1 assert len(result.errors) == 1
assert type(result.errors[0]) == InvalidMediaTypeValue assert type(result.errors[0]) == DeserializeError
assert result.data is None assert result.data is None
assert result.headers == {} assert result.headers == {}

View file

@ -1,23 +1,27 @@
import pytest import pytest
from openapi_core.deserializing.exceptions import DeserializeError
from openapi_core.deserializing.media_types.factories import (
MediaTypeDeserializersFactory,
)
from openapi_core.deserializing.parameters.factories import ( from openapi_core.deserializing.parameters.factories import (
ParameterDeserializersFactory, ParameterDeserializersFactory,
) )
from openapi_core.deserializing.parameters.exceptions import ( from openapi_core.deserializing.parameters.exceptions import (
EmptyParameterValue, EmptyParameterValue,
) )
from openapi_core.schema.media_types.models import MediaType
from openapi_core.schema.parameters.models import Parameter from openapi_core.schema.parameters.models import Parameter
@pytest.fixture
def deserializer_factory():
def create_deserializer(param):
return ParameterDeserializersFactory().create(param)
return create_deserializer
class TestParameterDeserialise(object): class TestParameterDeserialise(object):
@pytest.fixture
def deserializer_factory(self):
def create_deserializer(param):
return ParameterDeserializersFactory().create(param)
return create_deserializer
def test_deprecated(self, deserializer_factory): def test_deprecated(self, deserializer_factory):
param = Parameter('param', 'query', deprecated=True) param = Parameter('param', 'query', deprecated=True)
value = 'test' value = 'test'
@ -41,3 +45,27 @@ class TestParameterDeserialise(object):
result = deserializer_factory(param)(value) result = deserializer_factory(param)(value)
assert result == value assert result == value
class TestMediaTypeDeserialise(object):
@pytest.fixture
def deserializer_factory(self):
def create_deserializer(media_type):
return MediaTypeDeserializersFactory().create(media_type)
return create_deserializer
def test_empty(self, deserializer_factory):
media_type = MediaType('application/json')
value = ''
with pytest.raises(DeserializeError):
deserializer_factory(media_type)(value)
def test_no_schema_deserialised(self, deserializer_factory):
media_type = MediaType('application/json')
value = "{}"
result = deserializer_factory(media_type)(value)
assert result == {}

View file

@ -1,22 +0,0 @@
import pytest
from openapi_core.schema.media_types.exceptions import InvalidMediaTypeValue
from openapi_core.schema.media_types.models import MediaType
class TestMediaTypeDeserialise(object):
def test_empty(self):
media_type = MediaType('application/json')
value = ''
with pytest.raises(InvalidMediaTypeValue):
media_type.deserialise(value)
def test_no_schema_deserialised(self):
media_type = MediaType('application/json')
value = "{}"
result = media_type.deserialise(value)
assert result == {}