Skip to content

Commit 6d8b2e5

Browse files
committed
Move media deserializers to separate subpackage
1 parent 58d5c26 commit 6d8b2e5

File tree

10 files changed

+93
-93
lines changed

10 files changed

+93
-93
lines changed

openapi_core/deserializing/media_types/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from openapi_core.deserializing.exceptions import DeserializeError
2+
3+
4+
class PrimitiveDeserializer(object):
5+
6+
def __init__(self, mimetype, deserializer_callable):
7+
self.mimetype = mimetype
8+
self.deserializer_callable = deserializer_callable
9+
10+
def __call__(self, value):
11+
try:
12+
return self.deserializer_callable(value)
13+
except (ValueError, TypeError, AttributeError) as exc:
14+
raise DeserializeError(value, self.mimetype)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from openapi_core.schema.media_types.util import json_loads
2+
3+
from openapi_core.deserializing.media_types.deserializers import (
4+
PrimitiveDeserializer,
5+
)
6+
7+
8+
class MediaTypeDeserializersFactory(object):
9+
10+
MEDIA_TYPE_DESERIALIZERS = {
11+
'application/json': json_loads,
12+
}
13+
14+
def create(self, media_type):
15+
deserialize_callable = self.MEDIA_TYPE_DESERIALIZERS.get(
16+
media_type.mimetype, lambda x: x)
17+
return PrimitiveDeserializer(
18+
media_type.mimetype, deserialize_callable)

openapi_core/schema/media_types/exceptions.py

-8
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@ class OpenAPIMediaTypeError(OpenAPIMappingError):
77
pass
88

99

10-
@attr.s(hash=True)
11-
class InvalidMediaTypeValue(OpenAPIMediaTypeError):
12-
original_exception = attr.ib()
13-
14-
def __str__(self):
15-
return "Mimetype invalid: {0}".format(self.original_exception)
16-
17-
1810
@attr.s(hash=True)
1911
class InvalidContentType(OpenAPIMediaTypeError):
2012
mimetype = attr.ib()
-39
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,8 @@
11
"""OpenAPI core media types models module"""
2-
from collections import defaultdict
3-
4-
from openapi_core.schema.media_types.exceptions import InvalidMediaTypeValue
5-
from openapi_core.schema.media_types.util import json_loads
6-
from openapi_core.casting.schemas.exceptions import CastError
7-
8-
9-
MEDIA_TYPE_DESERIALIZERS = {
10-
'application/json': json_loads,
11-
}
12-
13-
142
class MediaType(object):
153
"""Represents an OpenAPI MediaType."""
164

175
def __init__(self, mimetype, schema=None, example=None):
186
self.mimetype = mimetype
197
self.schema = schema
208
self.example = example
21-
22-
def get_deserializer_mapping(self):
23-
mapping = MEDIA_TYPE_DESERIALIZERS.copy()
24-
return defaultdict(lambda: lambda x: x, mapping)
25-
26-
def get_dererializer(self):
27-
mapping = self.get_deserializer_mapping()
28-
return mapping[self.mimetype]
29-
30-
def deserialize(self, value):
31-
deserializer = self.get_dererializer()
32-
return deserializer(value)
33-
34-
def deserialise(self, value):
35-
try:
36-
return self.deserialize(value)
37-
except ValueError as exc:
38-
raise InvalidMediaTypeValue(exc)
39-
40-
def cast(self, value):
41-
if not self.schema:
42-
return value
43-
44-
try:
45-
return self.schema.cast(value)
46-
except CastError as exc:
47-
raise InvalidMediaTypeValue(exc)

openapi_core/validation/request/validators.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44

55
from openapi_core.casting.schemas.exceptions import CastError
66
from openapi_core.deserializing.exceptions import DeserializeError
7-
from openapi_core.schema.media_types.exceptions import (
8-
InvalidMediaTypeValue, InvalidContentType,
9-
)
7+
from openapi_core.schema.media_types.exceptions import InvalidContentType
108
from openapi_core.schema.operations.exceptions import InvalidOperation
119
from openapi_core.schema.parameters.enums import ParameterLocation
1210
from openapi_core.schema.parameters.exceptions import (
@@ -150,7 +148,7 @@ def _get_body(self, request, operation):
150148

151149
try:
152150
deserialised = self._deserialise_media_type(media_type, raw_body)
153-
except InvalidMediaTypeValue as exc:
151+
except DeserializeError as exc:
154152
return None, [exc, ]
155153

156154
try:
@@ -186,8 +184,14 @@ def _get_body_value(self, request_body, request):
186184
raise MissingRequestBody(request)
187185
return request.body
188186

189-
def _deserialise_media_type(self, param_or_media_type, value):
190-
return param_or_media_type.deserialise(value)
187+
def _deserialise_media_type(self, media_type, value):
188+
from openapi_core.deserializing.media_types.factories import (
189+
MediaTypeDeserializersFactory,
190+
)
191+
deserializers_factory = MediaTypeDeserializersFactory()
192+
deserializer = deserializers_factory.create(media_type)
193+
return deserializer(value)
194+
191195

192196
def _deserialise_parameter(self, param, value):
193197
from openapi_core.deserializing.parameters.factories import (

openapi_core/validation/response/validators.py

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
"""OpenAPI core validation response validators module"""
22
from openapi_core.casting.schemas.exceptions import CastError
3+
from openapi_core.deserializing.exceptions import DeserializeError
34
from openapi_core.schema.operations.exceptions import InvalidOperation
4-
from openapi_core.schema.media_types.exceptions import (
5-
InvalidMediaTypeValue, InvalidContentType,
6-
)
5+
from openapi_core.schema.media_types.exceptions import InvalidContentType
76
from openapi_core.schema.responses.exceptions import (
87
InvalidResponse, MissingResponseContent,
98
)
@@ -79,8 +78,8 @@ def _get_data(self, response, operation_response):
7978
return None, [exc, ]
8079

8180
try:
82-
deserialised = self._deserialise(media_type, raw_data)
83-
except InvalidMediaTypeValue as exc:
81+
deserialised = self._deserialise_media_type(media_type, raw_data)
82+
except DeserializeError as exc:
8483
return None, [exc, ]
8584

8685
try:
@@ -109,8 +108,13 @@ def _get_data_value(self, response):
109108

110109
return response.data
111110

112-
def _deserialise(self, param_or_media_type, value):
113-
return param_or_media_type.deserialise(value)
111+
def _deserialise_media_type(self, media_type, value):
112+
from openapi_core.deserializing.media_types.factories import (
113+
MediaTypeDeserializersFactory,
114+
)
115+
deserializers_factory = MediaTypeDeserializersFactory()
116+
deserializer = deserializers_factory.create(media_type)
117+
return deserializer(value)
114118

115119
def _cast(self, param_or_media_type, value):
116120
# return param_or_media_type.cast(value)

tests/integration/validation/test_validators.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
from six import text_type
55

66
from openapi_core.casting.schemas.exceptions import CastError
7+
from openapi_core.deserializing.exceptions import DeserializeError
78
from openapi_core.schema.media_types.exceptions import (
8-
InvalidContentType, InvalidMediaTypeValue,
9+
InvalidContentType,
910
)
1011
from openapi_core.extensions.models.models import BaseModel
1112
from openapi_core.schema.operations.exceptions import InvalidOperation
@@ -455,7 +456,7 @@ def test_invalid_media_type(self, validator):
455456
result = validator.validate(request, response)
456457

457458
assert len(result.errors) == 1
458-
assert type(result.errors[0]) == InvalidMediaTypeValue
459+
assert type(result.errors[0]) == DeserializeError
459460
assert result.data is None
460461
assert result.headers == {}
461462

tests/unit/deserializing/test_deserialize.py

+37-9
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
import pytest
22

3+
from openapi_core.deserializing.exceptions import DeserializeError
4+
from openapi_core.deserializing.media_types.factories import (
5+
MediaTypeDeserializersFactory,
6+
)
37
from openapi_core.deserializing.parameters.factories import (
4-
ParameterDeserializersFactory,
5-
)
8+
ParameterDeserializersFactory,
9+
)
610
from openapi_core.deserializing.parameters.exceptions import (
711
EmptyParameterValue,
812
)
13+
from openapi_core.schema.media_types.models import MediaType
914
from openapi_core.schema.parameters.models import Parameter
1015

1116

12-
@pytest.fixture
13-
def deserializer_factory():
14-
def create_deserializer(param):
15-
return ParameterDeserializersFactory().create(param)
16-
return create_deserializer
17-
18-
1917
class TestParameterDeserialise(object):
2018

19+
@pytest.fixture
20+
def deserializer_factory(self):
21+
def create_deserializer(param):
22+
return ParameterDeserializersFactory().create(param)
23+
return create_deserializer
24+
2125
def test_deprecated(self, deserializer_factory):
2226
param = Parameter('param', 'query', deprecated=True)
2327
value = 'test'
@@ -41,3 +45,27 @@ def test_query_valid(self, deserializer_factory):
4145
result = deserializer_factory(param)(value)
4246

4347
assert result == value
48+
49+
50+
class TestMediaTypeDeserialise(object):
51+
52+
@pytest.fixture
53+
def deserializer_factory(self):
54+
def create_deserializer(media_type):
55+
return MediaTypeDeserializersFactory().create(media_type)
56+
return create_deserializer
57+
58+
def test_empty(self, deserializer_factory):
59+
media_type = MediaType('application/json')
60+
value = ''
61+
62+
with pytest.raises(DeserializeError):
63+
deserializer_factory(media_type)(value)
64+
65+
def test_no_schema_deserialised(self, deserializer_factory):
66+
media_type = MediaType('application/json')
67+
value = "{}"
68+
69+
result = deserializer_factory(media_type)(value)
70+
71+
assert result == {}

tests/unit/schema/test_media_types.py

-22
This file was deleted.

0 commit comments

Comments
 (0)