Skip to content

Commit bf4179b

Browse files
committed
feat(BaseService): support stream=True in BaseService.send()
Fixes: arf/planning-sdk-squad/issues/901 This change allows generated operation code to pass 'stream=True' to the BaseService.send() method, which will in turn pass it on to the underlying requests.request() method. The net result is that the response body (even if it is a JSON object) will be "streamed", which means it will be made available via the requests.Response object rather than consumed and set on the DetailedResponse object. To access the streamed response, simply retrieve the requests.Response object by calling DetailedResponse.get_result(), then use the "iter_content" method on the returned requests.Response instance.
1 parent 7c6ad8b commit bf4179b

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

ibm_cloud_sdk_core/base_service.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,18 @@ def send(self, request: requests.Request, **kwargs) -> DetailedResponse:
211211
if self.disable_ssl_verification:
212212
kwargs['verify'] = False
213213

214+
# Check to see if the caller specified the 'stream' argument.
215+
stream_response = kwargs.get('stream') or False
216+
214217
try:
215218
response = requests.request(**request, cookies=self.jar, **kwargs)
216219

217220
if 200 <= response.status_code <= 299:
218221
if response.status_code == 204 or request['method'] == 'HEAD':
219222
# There is no body content for a HEAD request or a 204 response
220223
result = None
224+
elif stream_response:
225+
result = response
221226
elif not response.text:
222227
result = None
223228
else:

test/test_base_service.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import Optional
88
import pytest
99
import responses
10+
import requests
1011
import jwt
1112
from ibm_cloud_sdk_core import BaseService, DetailedResponse
1213
from ibm_cloud_sdk_core import ApiException
@@ -80,6 +81,13 @@ def head_request(self) -> DetailedResponse:
8081
response = self.send(request)
8182
return response
8283

84+
def get_document_as_stream(self) -> DetailedResponse:
85+
params = {'version': self.version}
86+
url = '/v1/streamjson'
87+
request = self.prepare_request(method='GET', url=url, params=params)
88+
response = self.send(request, stream=True)
89+
return response
90+
8391

8492
def get_access_token() -> str:
8593
access_token_layout = {
@@ -135,6 +143,45 @@ def test_url_encoding():
135143
assert 'version=2017-07-07' in responses.calls[0].request.url
136144

137145

146+
@responses.activate
147+
def test_stream_json_response():
148+
service = AnyServiceV1('2017-07-07', authenticator=NoAuthAuthenticator())
149+
150+
path = '/v1/streamjson'
151+
test_url = service.default_url + path
152+
153+
expected_response = json.dumps({"id": 1, "rev": "v1", "content": "this is a document"})
154+
155+
# print("Expected response: ", expected_response)
156+
157+
# Simulate a JSON response
158+
responses.add(
159+
responses.GET,
160+
test_url,
161+
status=200,
162+
body=expected_response,
163+
content_type='application/json')
164+
165+
# Invoke the operation and receive an "iterable" as the response
166+
response = service.get_document_as_stream()
167+
168+
assert response is not None
169+
assert len(responses.calls) == 1
170+
171+
# retrieve the requests.Response object from the DetailedResponse
172+
resp = response.get_result()
173+
assert isinstance(resp, requests.Response)
174+
assert hasattr(resp, "iter_content")
175+
176+
# Retrieve the response body, one chunk at a time.
177+
actual_response = ''
178+
for chunk in resp.iter_content(chunk_size=3):
179+
actual_response += chunk.decode("utf-8")
180+
181+
# print("Actual response: ", actual_response)
182+
assert actual_response == expected_response
183+
184+
138185
@responses.activate
139186
def test_http_config():
140187
service = AnyServiceV1('2017-07-07', authenticator=NoAuthAuthenticator())

0 commit comments

Comments
 (0)