Skip to content

Commit 87cb61a

Browse files
committed
Request binary format support
1 parent 16e7b1a commit 87cb61a

File tree

7 files changed

+69
-55
lines changed

7 files changed

+69
-55
lines changed

openapi_core/deserializing/media_types/util.py

+13-14
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,11 @@
1010
from werkzeug.datastructures import ImmutableMultiDict
1111

1212

13-
def binary_loads(value: Union[str, bytes], **parameters: str) -> bytes:
14-
charset = "utf-8"
15-
if "charset" in parameters:
16-
charset = parameters["charset"]
17-
if isinstance(value, str):
18-
return value.encode(charset)
13+
def binary_loads(value: bytes, **parameters: str) -> bytes:
1914
return value
2015

2116

22-
def plain_loads(value: Union[str, bytes], **parameters: str) -> str:
17+
def plain_loads(value: bytes, **parameters: str) -> str:
2318
charset = "utf-8"
2419
if "charset" in parameters:
2520
charset = parameters["charset"]
@@ -32,21 +27,25 @@ def plain_loads(value: Union[str, bytes], **parameters: str) -> str:
3227
return value
3328

3429

35-
def json_loads(value: Union[str, bytes], **parameters: str) -> Any:
30+
def json_loads(value: bytes, **parameters: str) -> Any:
3631
return loads(value)
3732

3833

3934
def xml_loads(value: Union[str, bytes], **parameters: str) -> Element:
40-
return fromstring(value)
35+
charset = "utf-8"
36+
if "charset" in parameters:
37+
charset = parameters["charset"]
38+
return fromstring(value.decode(charset))
4139

4240

43-
def urlencoded_form_loads(value: Any, **parameters: str) -> Mapping[str, Any]:
44-
return ImmutableMultiDict(parse_qsl(value))
41+
def urlencoded_form_loads(
42+
value: bytes, **parameters: str
43+
) -> Mapping[str, Any]:
44+
# only UTF-8 is conforming
45+
return ImmutableMultiDict(parse_qsl(value.decode("utf-8")))
4546

4647

47-
def data_form_loads(
48-
value: Union[str, bytes], **parameters: str
49-
) -> Mapping[str, Any]:
48+
def data_form_loads(value: bytes, **parameters: str) -> Mapping[str, Any]:
5049
if isinstance(value, bytes):
5150
value = value.decode("ASCII", errors="surrogateescape")
5251
boundary = ""

openapi_core/testing/requests.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __init__(
2020
view_args: Optional[Dict[str, Any]] = None,
2121
headers: Optional[Dict[str, Any]] = None,
2222
cookies: Optional[Dict[str, Any]] = None,
23-
data: Optional[str] = None,
23+
data: Optional[bytes] = None,
2424
content_type: str = "application/json",
2525
):
2626
self.host_url = host_url

tests/integration/test_petstore.py

+19-19
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ def test_post_birds(self, spec, spec_dict):
688688
"healthy": pet_healthy,
689689
},
690690
}
691-
data = json.dumps(data_json)
691+
data = json.dumps(data_json).encode()
692692
headers = {
693693
"api-key": self.api_key_encoded,
694694
}
@@ -770,7 +770,7 @@ def test_post_cats(self, spec, spec_dict):
770770
},
771771
"extra": None,
772772
}
773-
data = json.dumps(data_json)
773+
data = json.dumps(data_json).encode()
774774
headers = {
775775
"api-key": self.api_key_encoded,
776776
}
@@ -841,7 +841,7 @@ def test_post_cats_boolean_string(self, spec, spec_dict):
841841
"healthy": pet_healthy,
842842
},
843843
}
844-
data = json.dumps(data_json)
844+
data = json.dumps(data_json).encode()
845845
headers = {
846846
"api-key": self.api_key_encoded,
847847
}
@@ -915,7 +915,7 @@ def test_post_urlencoded(self, spec, spec_dict):
915915
"healthy": pet_healthy,
916916
},
917917
}
918-
data = urlencode(data_json)
918+
data = urlencode(data_json).encode()
919919
headers = {
920920
"api-key": self.api_key_encoded,
921921
}
@@ -985,7 +985,7 @@ def test_post_no_one_of_schema(self, spec):
985985
"name": pet_name,
986986
"alias": alias,
987987
}
988-
data = json.dumps(data_json)
988+
data = json.dumps(data_json).encode()
989989
headers = {
990990
"api-key": self.api_key_encoded,
991991
}
@@ -1037,7 +1037,7 @@ def test_post_cats_only_required_body(self, spec, spec_dict):
10371037
"healthy": pet_healthy,
10381038
},
10391039
}
1040-
data = json.dumps(data_json)
1040+
data = json.dumps(data_json).encode()
10411041
headers = {
10421042
"api-key": self.api_key_encoded,
10431043
}
@@ -1088,7 +1088,7 @@ def test_post_pets_raises_invalid_mimetype(self, spec):
10881088
"name": "Cat",
10891089
"tag": "cats",
10901090
}
1091-
data = json.dumps(data_json)
1091+
data = json.dumps(data_json).encode()
10921092
headers = {
10931093
"api-key": self.api_key_encoded,
10941094
}
@@ -1141,7 +1141,7 @@ def test_post_pets_missing_cookie(self, spec, spec_dict):
11411141
"healthy": pet_healthy,
11421142
},
11431143
}
1144-
data = json.dumps(data_json)
1144+
data = json.dumps(data_json).encode()
11451145
headers = {
11461146
"api-key": self.api_key_encoded,
11471147
}
@@ -1184,7 +1184,7 @@ def test_post_pets_missing_header(self, spec, spec_dict):
11841184
"healthy": pet_healthy,
11851185
},
11861186
}
1187-
data = json.dumps(data_json)
1187+
data = json.dumps(data_json).encode()
11881188
cookies = {
11891189
"user": "123",
11901190
}
@@ -1223,7 +1223,7 @@ def test_post_pets_raises_invalid_server_error(self, spec):
12231223
"name": "Cat",
12241224
"tag": "cats",
12251225
}
1226-
data = json.dumps(data_json)
1226+
data = json.dumps(data_json).encode()
12271227
headers = {
12281228
"api-key": "12345",
12291229
}
@@ -1509,7 +1509,7 @@ def test_post_tags_extra_body_properties(self, spec):
15091509
"name": pet_name,
15101510
"alias": alias,
15111511
}
1512-
data = json.dumps(data_json)
1512+
data = json.dumps(data_json).encode()
15131513

15141514
request = MockRequest(
15151515
host_url,
@@ -1539,7 +1539,7 @@ def test_post_tags_empty_body(self, spec):
15391539
host_url = "http://petstore.swagger.io/v1"
15401540
path_pattern = "/v1/tags"
15411541
data_json = {}
1542-
data = json.dumps(data_json)
1542+
data = json.dumps(data_json).encode()
15431543

15441544
request = MockRequest(
15451545
host_url,
@@ -1569,7 +1569,7 @@ def test_post_tags_wrong_property_type(self, spec):
15691569
host_url = "http://petstore.swagger.io/v1"
15701570
path_pattern = "/v1/tags"
15711571
tag_name = 123
1572-
data = json.dumps(tag_name)
1572+
data = json.dumps(tag_name).encode()
15731573

15741574
request = MockRequest(
15751575
host_url,
@@ -1602,7 +1602,7 @@ def test_post_tags_additional_properties(self, spec):
16021602
data_json = {
16031603
"name": pet_name,
16041604
}
1605-
data = json.dumps(data_json)
1605+
data = json.dumps(data_json).encode()
16061606

16071607
request = MockRequest(
16081608
host_url,
@@ -1658,7 +1658,7 @@ def test_post_tags_created_now(self, spec):
16581658
"created": created,
16591659
"name": pet_name,
16601660
}
1661-
data = json.dumps(data_json)
1661+
data = json.dumps(data_json).encode()
16621662

16631663
request = MockRequest(
16641664
host_url,
@@ -1715,7 +1715,7 @@ def test_post_tags_created_datetime(self, spec):
17151715
"created": created,
17161716
"name": pet_name,
17171717
}
1718-
data = json.dumps(data_json)
1718+
data = json.dumps(data_json).encode()
17191719

17201720
request = MockRequest(
17211721
host_url,
@@ -1787,7 +1787,7 @@ def test_post_tags_urlencoded(self, spec):
17871787
"created": created,
17881788
"name": pet_name,
17891789
}
1790-
data = urlencode(data_json)
1790+
data = urlencode(data_json).encode()
17911791
content_type = "application/x-www-form-urlencoded"
17921792

17931793
request = MockRequest(
@@ -1861,7 +1861,7 @@ def test_post_tags_created_invalid_type(self, spec):
18611861
"created": created,
18621862
"name": pet_name,
18631863
}
1864-
data = json.dumps(data_json)
1864+
data = json.dumps(data_json).encode()
18651865

18661866
request = MockRequest(
18671867
host_url,
@@ -1918,7 +1918,7 @@ def test_delete_tags_with_requestbody(self, spec):
19181918
data_json = {
19191919
"ids": ids,
19201920
}
1921-
data = json.dumps(data_json)
1921+
data = json.dumps(data_json).encode()
19221922
request = MockRequest(
19231923
host_url,
19241924
"DELETE",

tests/integration/unmarshalling/test_read_only_write_only.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def test_write_a_read_only_property(self, request_unmarshaller):
3737
"id": 10,
3838
"name": "Pedro",
3939
}
40-
)
40+
).encode()
4141

4242
request = MockRequest(
4343
host_url="", method="POST", path="/users", data=data
@@ -77,7 +77,7 @@ def test_write_only_property(self, request_unmarshaller):
7777
"name": "Pedro",
7878
"hidden": False,
7979
}
80-
)
80+
).encode()
8181

8282
request = MockRequest(
8383
host_url="", method="POST", path="/users", data=data
@@ -98,7 +98,7 @@ def test_read_a_write_only_property(self, response_unmarshaller):
9898
"name": "Pedro",
9999
"hidden": True,
100100
}
101-
)
101+
).encode()
102102

103103
request = MockRequest(host_url="", method="POST", path="/users")
104104
response = MockResponse(data)

tests/integration/unmarshalling/test_request_unmarshaller.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def test_missing_body(self, request_unmarshaller):
174174
)
175175

176176
def test_invalid_content_type(self, request_unmarshaller):
177-
data = "csv,data"
177+
data = b"csv,data"
178178
headers = {
179179
"api-key": self.api_key_encoded,
180180
}
@@ -231,7 +231,7 @@ def test_invalid_complex_parameter(self, request_unmarshaller, spec_dict):
231231
"healthy": True,
232232
},
233233
}
234-
data = json.dumps(data_json)
234+
data = json.dumps(data_json).encode()
235235
headers = {
236236
"api-key": self.api_key_encoded,
237237
}
@@ -296,7 +296,7 @@ def test_post_pets(self, request_unmarshaller, spec_dict):
296296
"healthy": True,
297297
},
298298
}
299-
data = json.dumps(data_json)
299+
data = json.dumps(data_json).encode()
300300
headers = {
301301
"api-key": self.api_key_encoded,
302302
}
@@ -338,7 +338,7 @@ def test_post_pets(self, request_unmarshaller, spec_dict):
338338
assert result.body.address.city == pet_city
339339

340340
def test_post_pets_plain_no_schema(self, request_unmarshaller):
341-
data = "plain text"
341+
data = b"plain text"
342342
headers = {
343343
"api-key": self.api_key_encoded,
344344
}
@@ -368,7 +368,7 @@ def test_post_pets_plain_no_schema(self, request_unmarshaller):
368368
},
369369
)
370370
assert result.security == {}
371-
assert result.body == data
371+
assert result.body == data.decode()
372372

373373
def test_get_pet_unauthorized(self, request_unmarshaller):
374374
request = MockRequest(

tests/integration/validation/test_request_validators.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def test_security_not_found(self, request_validator):
8989
)
9090

9191
def test_media_type_not_found(self, request_validator):
92-
data = "csv,data"
92+
data = b"csv,data"
9393
headers = {
9494
"api-key": self.api_key_encoded,
9595
}

0 commit comments

Comments
 (0)