Skip to content
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
2 changes: 1 addition & 1 deletion docs/_components/storage-getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ The :class:`Connection <gcloud.storage.connection.Connection>` object
itself is iterable, so you can loop over it, or call ``list`` on it to get
a list object::

>>> for bucket in connection:
>>> for bucket in connection.get_all_buckets():
... print bucket.name
>>> print list(connection)

Expand Down
12 changes: 12 additions & 0 deletions gcloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ def __iter__(self):
def __contains__(self, blob):
return self.get_blob(blob) is not None

def exists(self):
"""Determines whether or not this bucket exists.

:rtype: boolean
:returns: True if the bucket exists in Cloud Storage.
"""
try:
self.connection.get_bucket(self.name)
return True
except NotFound:
return False

@property
def acl(self):
"""Create our ACL on demand."""
Expand Down
24 changes: 2 additions & 22 deletions gcloud/storage/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

from gcloud.connection import Connection as _Base
from gcloud.exceptions import make_exception
from gcloud.exceptions import NotFound
from gcloud.storage.bucket import Bucket
from gcloud.storage.iterator import Iterator

Expand Down Expand Up @@ -57,15 +56,9 @@ class Connection(_Base):
A :class:`Connection` is actually iterable and will return the
:class:`gcloud.storage.bucket.Bucket` objects inside the project::

>>> for bucket in connection:
>>> for bucket in connection.get_all_buckets():
>>> print bucket
<Bucket: my-bucket-name>

In that same way, you can check for whether a bucket exists inside
the project using Python's ``in`` operator::

>>> print 'my-bucket-name' in connection
True
"""

API_VERSION = 'v1'
Expand All @@ -82,16 +75,6 @@ def __init__(self, project, *args, **kwargs):
super(Connection, self).__init__(*args, **kwargs)
self.project = project

def __iter__(self):
return iter(_BucketIterator(connection=self))

def __contains__(self, bucket_name):
try:
self.get_bucket(bucket_name)
return True
except NotFound:
return False

def build_api_url(self, path, query_params=None, api_base_url=None,
api_version=None, upload=False):
"""Construct an API url given a few components, some optional.
Expand Down Expand Up @@ -265,14 +248,11 @@ def get_all_buckets(self):
>>> connection = storage.get_connection(project)
>>> for bucket in connection.get_all_buckets():
>>> print bucket
>>> # ... is the same as ...
>>> for bucket in connection:
>>> print bucket

:rtype: list of :class:`gcloud.storage.bucket.Bucket` objects.
:returns: All buckets belonging to this project.
"""
return list(self)
return iter(_BucketIterator(connection=self))

def get_bucket(self, bucket_name):
"""Get a bucket by name.
Expand Down
33 changes: 33 additions & 0 deletions gcloud/storage/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,39 @@ def test___contains___hit(self):
self.assertEqual(kw['method'], 'GET')
self.assertEqual(kw['path'], '/b/%s/o/%s' % (NAME, BLOB_NAME))

def test_exists_miss(self):
from gcloud.exceptions import NotFound

class _FakeConnection(object):

_called_with = []

@classmethod
def get_bucket(cls, bucket_name):
cls._called_with.append(bucket_name)
raise NotFound(bucket_name)

NAME = 'name'
bucket = self._makeOne(connection=_FakeConnection, name=NAME)
self.assertFalse(bucket.exists())
self.assertEqual(_FakeConnection._called_with, [NAME])

def test_exists_hit(self):
class _FakeConnection(object):

_called_with = []

@classmethod
def get_bucket(cls, bucket_name):
cls._called_with.append(bucket_name)
# exists() does not use the return value
return object()

NAME = 'name'
bucket = self._makeOne(connection=_FakeConnection, name=NAME)
self.assertTrue(bucket.exists())
self.assertEqual(_FakeConnection._called_with, [NAME])

def test_acl_property(self):
from gcloud.storage.acl import BucketACL
bucket = self._makeOne()
Expand Down
90 changes: 7 additions & 83 deletions gcloud/storage/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,82 +63,6 @@ def authorize(self, http):
self.assertTrue(conn.http is authorized)
self.assertTrue(isinstance(creds._called_with, httplib2.Http))

def test___iter___empty(self):
PROJECT = 'project'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
'storage',
conn.API_VERSION,
'b?project=%s' % PROJECT,
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
'{}',
)
blobs = list(conn)
self.assertEqual(len(blobs), 0)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test___iter___non_empty(self):
PROJECT = 'project'
BLOB_NAME = 'blob-name'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
'storage',
conn.API_VERSION,
'b?project=%s' % PROJECT,
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
'{"items": [{"name": "%s"}]}' % BLOB_NAME,
)
blobs = list(conn)
self.assertEqual(len(blobs), 1)
self.assertEqual(blobs[0].name, BLOB_NAME)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test___contains___miss(self):
PROJECT = 'project'
NONESUCH = 'nonesuch'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
'storage',
conn.API_VERSION,
'b',
'nonesuch?project=%s' % PROJECT,
])
http = conn._http = Http(
{'status': '404', 'content-type': 'application/json'},
'{}',
)
self.assertFalse(NONESUCH in conn)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test___contains___hit(self):
PROJECT = 'project'
BLOB_NAME = 'blob-name'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
'storage',
conn.API_VERSION,
'b',
'%s?project=%s' % (BLOB_NAME, PROJECT),
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
'{"name": "%s"}' % BLOB_NAME,
)
self.assertTrue(BLOB_NAME in conn)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test_build_api_url_no_extra_query_params(self):
PROJECT = 'project'
conn = self._makeOne(PROJECT)
Expand Down Expand Up @@ -370,14 +294,14 @@ def test_get_all_buckets_empty(self):
{'status': '200', 'content-type': 'application/json'},
'{}',
)
blobs = conn.get_all_buckets()
self.assertEqual(len(blobs), 0)
buckets = list(conn.get_all_buckets())
self.assertEqual(len(buckets), 0)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test_get_all_buckets_non_empty(self):
PROJECT = 'project'
BLOB_NAME = 'blob-name'
BUCKET_NAME = 'bucket-name'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
Expand All @@ -387,11 +311,11 @@ def test_get_all_buckets_non_empty(self):
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
'{"items": [{"name": "%s"}]}' % BLOB_NAME,
'{"items": [{"name": "%s"}]}' % BUCKET_NAME,
)
blobs = conn.get_all_buckets()
self.assertEqual(len(blobs), 1)
self.assertEqual(blobs[0].name, BLOB_NAME)
buckets = list(conn.get_all_buckets())
self.assertEqual(len(buckets), 1)
self.assertEqual(buckets[0].name, BUCKET_NAME)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

Expand Down