Skip to content

Commit 43deb7f

Browse files
committed
Using 'fields' in Blob.exists() to reduce payload size.
1 parent 6d147c8 commit 43deb7f

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

gcloud/storage/blob.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from _gcloud_vendor.apitools.base.py import transfer
2929

3030
from gcloud.credentials import generate_signed_url
31+
from gcloud.exceptions import NotFound
3132
from gcloud.storage._helpers import _PropertyMixin
3233
from gcloud.storage._helpers import _scalar_property
3334
from gcloud.storage import _implicit_environ
@@ -174,7 +175,15 @@ def exists(self):
174175
:rtype: boolean
175176
:returns: True if the blob exists in Cloud Storage.
176177
"""
177-
return self.bucket.get_blob(self.name) is not None
178+
try:
179+
# We only need the status code (200 or not) so we seek to
180+
# minimize the returned payload.
181+
query_params = {'fields': 'name'}
182+
self.connection.api_request(method='GET', path=self.path,
183+
query_params=query_params)
184+
return True
185+
except NotFound:
186+
return False
178187

179188
def rename(self, new_name):
180189
"""Renames this blob using copy and delete operations.

gcloud/storage/test_blob.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,19 @@ def test_generate_signed_url_w_explicit_method(self):
216216
self.assertEqual(SIGNER._signed, [(EXPECTED_ARGS, EXPECTED_KWARGS)])
217217

218218
def test_exists_miss(self):
219+
from six.moves.http_client import NOT_FOUND
219220
NONESUCH = 'nonesuch'
220-
connection = _Connection()
221+
not_found_response = {'status': NOT_FOUND}
222+
connection = _Connection(not_found_response)
221223
bucket = _Bucket(connection)
222224
blob = self._makeOne(NONESUCH, bucket=bucket)
223225
self.assertFalse(blob.exists())
224226

225227
def test_exists_hit(self):
228+
from six.moves.http_client import OK
226229
BLOB_NAME = 'blob-name'
227-
connection = _Connection()
230+
found_response = {'status': OK}
231+
connection = _Connection(found_response)
228232
bucket = _Bucket(connection)
229233
blob = self._makeOne(BLOB_NAME, bucket=bucket)
230234
bucket._blobs[BLOB_NAME] = 1
@@ -245,8 +249,10 @@ def test_rename(self):
245249
self.assertTrue(NEW_NAME in bucket._blobs)
246250

247251
def test_delete(self):
252+
from six.moves.http_client import NOT_FOUND
248253
BLOB_NAME = 'blob-name'
249-
connection = _Connection()
254+
not_found_response = {'status': NOT_FOUND}
255+
connection = _Connection(not_found_response)
250256
bucket = _Bucket(connection)
251257
blob = self._makeOne(BLOB_NAME, bucket=bucket)
252258
bucket._blobs[BLOB_NAME] = 1
@@ -1000,7 +1006,12 @@ def __init__(self, *responses):
10001006
self.http = _HTTP(*responses)
10011007

10021008
def api_request(self, **kw):
1003-
return self._respond(**kw)
1009+
from six.moves.http_client import NOT_FOUND
1010+
from gcloud.exceptions import NotFound
1011+
result = self._respond(**kw)
1012+
if result.get('status') == NOT_FOUND:
1013+
raise NotFound(result)
1014+
return result
10041015

10051016
def build_api_url(self, path, query_params=None,
10061017
api_base_url=API_BASE_URL, upload=False):
@@ -1031,9 +1042,6 @@ def __init__(self, connection):
10311042
self._blobs = {}
10321043
self._deleted = []
10331044

1034-
def get_blob(self, blob_name):
1035-
return self._blobs.get(blob_name)
1036-
10371045
def copy_blob(self, blob, destination_bucket, new_name):
10381046
destination_bucket._blobs[new_name] = self._blobs[blob.name]
10391047
return blob.__class__(None, bucket=destination_bucket,

0 commit comments

Comments
 (0)