Skip to content

Commit dd1cd05

Browse files
authored
fix: use on-the-fly compression only for file objects (#177)
When we introduced the new `GzipStream` utility class which handles the on-the-fly compression of the file like object. We also started using it for in-memory objects, like bytes, but it has introduced a minor incompatibility with the existing SDKs. This commit introduces a fix for that, by using the new utility class only for file-like objects and handling the other types as before (compressing in memory). Signed-off-by: Norbert Biczo <[email protected]>
1 parent 5d52d98 commit dd1cd05

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

ibm_cloud_sdk_core/base_service.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
import gzip
18+
import io
1719
import json as json_import
1820
import logging
1921
import platform
@@ -421,7 +423,13 @@ def prepare_request(
421423
if self.get_enable_gzip_compression() and 'content-encoding' not in headers and request['data'] is not None:
422424
headers['content-encoding'] = 'gzip'
423425
request['headers'] = headers
424-
request['data'] = GzipStream(request['data'])
426+
# If the provided data is a file-like object, we create `GzipStream` which will handle
427+
# the compression on-the-fly when the requests package starts reading its content.
428+
# This helps avoid OOM errors when the opened file is too big.
429+
# In any other cases, we use the in memory compression directly from
430+
# the `gzip` package for backward compatibility.
431+
raw_data = request['data']
432+
request['data'] = GzipStream(raw_data) if isinstance(raw_data, io.IOBase) else gzip.compress(raw_data)
425433

426434
# Next, we need to process the 'files' argument to try to fill in
427435
# any missing filenames where possible.

test/test_base_service.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -607,13 +607,13 @@ def test_gzip_compression():
607607
service.set_enable_gzip_compression(True)
608608
assert service.get_enable_gzip_compression()
609609
prepped = service.prepare_request('GET', url='', data=json.dumps({"foo": "bar"}))
610-
assert prepped['data'].read() == gzip.compress(b'{"foo": "bar"}')
610+
assert prepped['data'] == gzip.compress(b'{"foo": "bar"}')
611611
assert prepped['headers'].get('content-encoding') == 'gzip'
612612

613613
# Should return compressed data when gzip is on for non-json data
614614
assert service.get_enable_gzip_compression()
615615
prepped = service.prepare_request('GET', url='', data=b'rawdata')
616-
assert prepped['data'].read() == gzip.compress(b'rawdata')
616+
assert prepped['data'] == gzip.compress(b'rawdata')
617617
assert prepped['headers'].get('content-encoding') == 'gzip'
618618

619619
# Should return compressed data when gzip is on for gzip file data
@@ -624,7 +624,7 @@ def test_gzip_compression():
624624
with gzip.GzipFile(mode='rb', fileobj=t_f) as gz_f:
625625
gzip_data = gz_f.read()
626626
prepped = service.prepare_request('GET', url='', data=gzip_data)
627-
assert prepped['data'].read() == gzip.compress(t_f.read())
627+
assert prepped['data'] == gzip.compress(t_f.read())
628628
assert prepped['headers'].get('content-encoding') == 'gzip'
629629

630630
# Should return compressed json data when gzip is on for gzip file json data
@@ -635,7 +635,7 @@ def test_gzip_compression():
635635
with gzip.GzipFile(mode='rb', fileobj=t_f) as gz_f:
636636
gzip_data = gz_f.read()
637637
prepped = service.prepare_request('GET', url='', data=gzip_data)
638-
assert prepped['data'].read() == gzip.compress(t_f.read())
638+
assert prepped['data'] == gzip.compress(t_f.read())
639639
assert prepped['headers'].get('content-encoding') == 'gzip'
640640

641641
# Should return uncompressed data when content-encoding is set
@@ -715,7 +715,7 @@ def test_gzip_compression_external():
715715
assert service.service_url == 'https://mockurl'
716716
assert service.get_enable_gzip_compression() is True
717717
prepped = service.prepare_request('GET', url='', data=json.dumps({"foo": "bar"}))
718-
assert prepped['data'].read() == gzip.compress(b'{"foo": "bar"}')
718+
assert prepped['data'] == gzip.compress(b'{"foo": "bar"}')
719719
assert prepped['headers'].get('content-encoding') == 'gzip'
720720

721721

0 commit comments

Comments
 (0)