Skip to content

Commit d6be0ce

Browse files
committed
Requests chunk encoded request handling
1 parent 4658b25 commit d6be0ce

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

openapi_core/contrib/requests/requests.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""OpenAPI core contrib requests requests module"""
2+
from typing import Mapping
23
from typing import Optional
34
from typing import Union
45
from urllib.parse import parse_qs
@@ -7,6 +8,7 @@
78
from requests import PreparedRequest
89
from requests import Request
910
from requests.cookies import RequestsCookieJar
11+
from requests.utils import rewind_body
1012
from werkzeug.datastructures import Headers
1113
from werkzeug.datastructures import ImmutableMultiDict
1214

@@ -67,6 +69,17 @@ def method(self) -> str:
6769
def body(self) -> Optional[str]:
6870
if self.request.body is None:
6971
return None
72+
is_stream = all(
73+
[
74+
hasattr(self.request.body, "__iter__"),
75+
not isinstance(self.request.body, (str, list, tuple, Mapping)),
76+
]
77+
)
78+
if is_stream:
79+
chunks = list(self.request.body)
80+
body = "".join(chunks)
81+
self.request.body = (x for x in chunks)
82+
return body
7083
if isinstance(self.request.body, bytes):
7184
return self.request.body.decode("utf-8")
7285
assert isinstance(self.request.body, str)

tests/integration/contrib/requests/test_requests_validation.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from types import GeneratorType
2+
13
import pytest
24
import requests
35
import responses
@@ -72,6 +74,22 @@ def test_request_validator_path_pattern(self, request_unmarshaller):
7274
result = request_unmarshaller.unmarshal(openapi_request)
7375
assert not result.errors
7476

77+
def test_request_validator_encoded_chunks(self, request_unmarshaller):
78+
def gen():
79+
yield '{"param1": 1}'
80+
81+
request = requests.Request(
82+
"POST",
83+
"http://localhost/browse/12/",
84+
params={"q": "string"},
85+
headers={"content-type": "application/json"},
86+
data=gen(),
87+
)
88+
openapi_request = RequestsOpenAPIRequest(request)
89+
result = request_unmarshaller.unmarshal(openapi_request)
90+
assert not result.errors
91+
assert request.data is GeneratorType
92+
7593
def test_request_validator_prepared_request(self, request_unmarshaller):
7694
request = requests.Request(
7795
"POST",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy