Skip to content

Commit cfe4a7c

Browse files
authored
Merge pull request #303 from p1c2u/feature/deserialize-data-form-media-type
deserialize data form media type
2 parents 7a83f01 + 5f62c62 commit cfe4a7c

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

openapi_core/deserializing/media_types/factories.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from openapi_core.deserializing.media_types.util import json_loads, form_loads
1+
from openapi_core.deserializing.media_types.util import (
2+
json_loads, urlencoded_form_loads, data_form_loads,
3+
)
24

35
from openapi_core.deserializing.media_types.deserializers import (
46
PrimitiveDeserializer,
@@ -9,7 +11,8 @@ class MediaTypeDeserializersFactory(object):
911

1012
MEDIA_TYPE_DESERIALIZERS = {
1113
'application/json': json_loads,
12-
'application/x-www-form-urlencoded': form_loads,
14+
'application/x-www-form-urlencoded': urlencoded_form_loads,
15+
'multipart/form-data': data_form_loads,
1316
}
1417

1518
def __init__(self, custom_deserializers=None):

openapi_core/deserializing/media_types/util.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from email.parser import Parser
12
from json import loads
23

34
from six import binary_type
@@ -11,5 +12,19 @@ def json_loads(value):
1112
return loads(value)
1213

1314

14-
def form_loads(value):
15+
def urlencoded_form_loads(value):
1516
return dict(parse_qsl(value))
17+
18+
19+
def data_form_loads(value):
20+
if issubclass(type(value), binary_type):
21+
value = value.decode('ASCII', errors='surrogateescape')
22+
parser = Parser()
23+
parts = parser.parsestr(value, headersonly=False)
24+
return dict(
25+
(
26+
part.get_param('name', header='content-disposition'),
27+
part.get_payload(decode=True),
28+
)
29+
for part in parts.get_payload()
30+
)

tests/unit/deserializing/test_media_types_deserializers.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import pytest
22

3+
from six import b, u
4+
35
from openapi_core.deserializing.exceptions import DeserializeError
46
from openapi_core.deserializing.media_types.factories import (
57
MediaTypeDeserializersFactory,
@@ -31,22 +33,46 @@ def test_json_empty_object(self, deserializer_factory):
3133

3234
assert result == {}
3335

34-
def test_form_urlencoded_empty(self, deserializer_factory):
36+
def test_urlencoded_form_empty(self, deserializer_factory):
3537
media_type = MediaType('application/x-www-form-urlencoded')
3638
value = ''
3739

3840
result = deserializer_factory(media_type)(value)
3941

4042
assert result == {}
4143

42-
def test_form_urlencoded_simple(self, deserializer_factory):
44+
def test_urlencoded_form_simple(self, deserializer_factory):
4345
media_type = MediaType('application/x-www-form-urlencoded')
4446
value = 'param1=test'
4547

4648
result = deserializer_factory(media_type)(value)
4749

4850
assert result == {'param1': 'test'}
4951

52+
@pytest.mark.parametrize('value', [b(''), u('')])
53+
def test_data_form_empty(self, deserializer_factory, value):
54+
media_type = MediaType('multipart/form-data')
55+
56+
result = deserializer_factory(media_type)(value)
57+
58+
assert result == {}
59+
60+
def test_data_form_simple(self, deserializer_factory):
61+
media_type = MediaType('multipart/form-data')
62+
value = b(
63+
'Content-Type: multipart/form-data; boundary="'
64+
'===============2872712225071193122=="\n'
65+
'MIME-Version: 1.0\n\n'
66+
'--===============2872712225071193122==\n'
67+
'Content-Type: text/plain\nMIME-Version: 1.0\n'
68+
'Content-Disposition: form-data; name="param1"\n\ntest\n'
69+
'--===============2872712225071193122==--\n'
70+
)
71+
72+
result = deserializer_factory(media_type)(value)
73+
74+
assert result == {'param1': b('test')}
75+
5076
def test_custom_simple(self, deserializer_factory):
5177
custom_mimetype = 'application/custom'
5278
media_type = MediaType(custom_mimetype)

0 commit comments

Comments
 (0)