Skip to content

Commit

Permalink
fix: Do not store data in-memory during download process in Python (b…
Browse files Browse the repository at this point in the history
  • Loading branch information
box-sdk-build authored Aug 30, 2024
1 parent 34e0e80 commit 7c645ae
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .codegen.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ "engineHash": "2bf4a47", "specHash": "57614c2", "version": "1.4.0" }
{ "engineHash": "a3c5813", "specHash": "739d87b", "version": "1.4.0" }
80 changes: 56 additions & 24 deletions box_sdk_gen/internal/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import uuid
from time import time
from enum import Enum
from io import SEEK_END, SEEK_SET, BufferedIOBase, BytesIO
from io import SEEK_CUR, SEEK_END, SEEK_SET, BufferedIOBase, BytesIO
from typing import Any, Callable, Dict, Iterable, Optional, TypeVar

try:
Expand All @@ -26,41 +26,73 @@

class ResponseByteStream(ByteStream):
def __init__(self, request_iterator):
self._bytes = BytesIO()
self._iterator = request_iterator

def _load_all(self):
self._bytes.seek(0, SEEK_END)
for chunk in self._iterator:
self._bytes.write(chunk)

def _load_until(self, goal_position):
current_position = self._bytes.seek(0, SEEK_END)
while current_position < goal_position:
self._buffer = b''
self._position = 0
self._eos = False

def _read_from_iterator(self, size):
"""
Read up to `size` bytes from the iterator into the buffer
:param size: Number of bytes to read. If None, read the entire stream.
"""
if self._eos:
return

while len(self._buffer) < size:
try:
current_position += self._bytes.write(next(self._iterator))
chunk = next(self._iterator)
self._buffer += chunk
except StopIteration:
self._eos = True
break

def tell(self):
return self._bytes.tell()
"""
Returns the current position in the stream
:return:
"""
return self._position

def read(self, size=None):
left_off_at = self._bytes.tell()
"""
Reads up to `size` bytes from the stream
:param size: Read up to `size` bytes from the stream. If None read the entire stream.
:return: Bytes read from the stream
"""
if size is None:
self._load_all()
else:
goal_position = left_off_at + size
self._load_until(goal_position)

self._bytes.seek(left_off_at)
return self._bytes.read(size)
# Read everything remaining in the stream.
result = self._buffer + b''.join(self._iterator)
self._buffer = b''
self._position += len(result)
self._eos = True
return result

self._read_from_iterator(size)
result = self._buffer[:size]
self._buffer = self._buffer[size:]
self._position += len(result)
return result

def seek(self, position, whence=SEEK_SET):
if whence == SEEK_END:
self._load_all()
"""
Move the stream to given position
:param position: Position to move to
:param whence: One of SEEK_SET = 0, SEEK_CUR = 1 or SEEK_END = 2
:return: The new position in the stream
"""
if whence == SEEK_SET:
if position < self._position:
raise ValueError('Cannot seek backwards in a stream')
self.read(position - self._position)
elif whence == SEEK_CUR:
self.read(position)
elif whence == SEEK_END:
raise NotImplementedError('SEEK_END is not supported for streams')
else:
self._bytes.seek(position, whence)
raise ValueError('Invalid value for `whence`')

return self._position


def get_env_var(name: str) -> str:
Expand Down
6 changes: 3 additions & 3 deletions box_sdk_gen/managers/folder_classifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def get_classification_on_folder(
URL explicitly, for example
`/folders/:id//enterprise_12345/securityClassification-6VMVochwUWo`.
`/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`.
:param folder_id: The unique identifier that represent a folder.
Expand Down Expand Up @@ -164,7 +164,7 @@ def add_classification_to_folder(
URL explicitly, for example
`/folders/:id//enterprise_12345/securityClassification-6VMVochwUWo`.
`/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`.
:param folder_id: The unique identifier that represent a folder.
Expand Down Expand Up @@ -289,7 +289,7 @@ def delete_classification_from_folder(
URL explicitly, for example
`/folders/:id//enterprise_12345/securityClassification-6VMVochwUWo`.
`/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`.
:param folder_id: The unique identifier that represent a folder.
Expand Down
6 changes: 3 additions & 3 deletions docs/folder_classifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ has been applied to a folder.

This API can also be called by including the enterprise ID in the
URL explicitly, for example
`/folders/:id//enterprise_12345/securityClassification-6VMVochwUWo`.
`/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`.

This operation is performed by calling function `get_classification_on_folder`.

Expand Down Expand Up @@ -48,7 +48,7 @@ classification to add.

This API can also be called by including the enterprise ID in the
URL explicitly, for example
`/folders/:id//enterprise_12345/securityClassification-6VMVochwUWo`.
`/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`.

This operation is performed by calling function `add_classification_to_folder`.

Expand Down Expand Up @@ -122,7 +122,7 @@ Removes any classifications from a folder.

This API can also be called by including the enterprise ID in the
URL explicitly, for example
`/folders/:id//enterprise_12345/securityClassification-6VMVochwUWo`.
`/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`.

This operation is performed by calling function `delete_classification_from_folder`.

Expand Down

0 comments on commit 7c645ae

Please sign in to comment.