Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using 'fields' in Blob.exists() to reduce payload size. #731

Merged
merged 1 commit into from
Mar 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion gcloud/storage/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from _gcloud_vendor.apitools.base.py import transfer

from gcloud.credentials import generate_signed_url
from gcloud.exceptions import NotFound
from gcloud.storage._helpers import _PropertyMixin
from gcloud.storage._helpers import _scalar_property
from gcloud.storage import _implicit_environ
Expand Down Expand Up @@ -174,7 +175,15 @@ def exists(self):
:rtype: boolean
:returns: True if the blob exists in Cloud Storage.
"""
return self.bucket.get_blob(self.name) is not None
try:
# We only need the status code (200 or not) so we seek to
# minimize the returned payload.
query_params = {'fields': 'name'}
self.connection.api_request(method='GET', path=self.path,
query_params=query_params)
return True
except NotFound:
return False

def rename(self, new_name):
"""Renames this blob using copy and delete operations.
Expand Down
22 changes: 15 additions & 7 deletions gcloud/storage/test_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,19 @@ def test_generate_signed_url_w_explicit_method(self):
self.assertEqual(SIGNER._signed, [(EXPECTED_ARGS, EXPECTED_KWARGS)])

def test_exists_miss(self):
from six.moves.http_client import NOT_FOUND
NONESUCH = 'nonesuch'
connection = _Connection()
not_found_response = {'status': NOT_FOUND}
connection = _Connection(not_found_response)
bucket = _Bucket(connection)
blob = self._makeOne(NONESUCH, bucket=bucket)
self.assertFalse(blob.exists())

def test_exists_hit(self):
from six.moves.http_client import OK
BLOB_NAME = 'blob-name'
connection = _Connection()
found_response = {'status': OK}
connection = _Connection(found_response)
bucket = _Bucket(connection)
blob = self._makeOne(BLOB_NAME, bucket=bucket)
bucket._blobs[BLOB_NAME] = 1
Expand All @@ -245,8 +249,10 @@ def test_rename(self):
self.assertTrue(NEW_NAME in bucket._blobs)

def test_delete(self):
from six.moves.http_client import NOT_FOUND
BLOB_NAME = 'blob-name'
connection = _Connection()
not_found_response = {'status': NOT_FOUND}
connection = _Connection(not_found_response)
bucket = _Bucket(connection)
blob = self._makeOne(BLOB_NAME, bucket=bucket)
bucket._blobs[BLOB_NAME] = 1
Expand Down Expand Up @@ -1000,7 +1006,12 @@ def __init__(self, *responses):
self.http = _HTTP(*responses)

def api_request(self, **kw):
return self._respond(**kw)
from six.moves.http_client import NOT_FOUND
from gcloud.exceptions import NotFound
result = self._respond(**kw)
if result.get('status') == NOT_FOUND:
raise NotFound(result)
return result

def build_api_url(self, path, query_params=None,
api_base_url=API_BASE_URL, upload=False):
Expand Down Expand Up @@ -1031,9 +1042,6 @@ def __init__(self, connection):
self._blobs = {}
self._deleted = []

def get_blob(self, blob_name):
return self._blobs.get(blob_name)

def copy_blob(self, blob, destination_bucket, new_name):
destination_bucket._blobs[new_name] = self._blobs[blob.name]
return blob.__class__(None, bucket=destination_bucket,
Expand Down