Skip to content

Commit

Permalink
STORAGE: Making Connection.create_bucket a standalone method.
Browse files Browse the repository at this point in the history
  • Loading branch information
dhermes committed Mar 12, 2015
1 parent 66dc298 commit f21cacf
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 65 deletions.
2 changes: 1 addition & 1 deletion docs/_components/storage-getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ bucket.

Let's create a bucket:

>>> bucket = connection.create_bucket('test')
>>> bucket = storage.create_bucket('test', connection=connection)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "gcloud/storage/connection.py", line 340, in create_bucket
Expand Down
2 changes: 1 addition & 1 deletion docs/_components/storage-quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ you can create buckets and blobs::
>>> from gcloud import storage
>>> storage.get_all_buckets(connection)
[<Bucket: ...>, ...]
>>> bucket = connection.create_bucket('my-new-bucket')
>>> bucket = storage.create_bucket('my-new-bucket', connection=connection)
>>> print bucket
<Bucket: my-new-bucket>
>>> blob = bucket.new_blob('my-test-file.txt')
Expand Down
1 change: 1 addition & 0 deletions gcloud/storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from gcloud.storage._implicit_environ import get_default_bucket
from gcloud.storage._implicit_environ import get_default_connection
from gcloud.storage._implicit_environ import get_default_project
from gcloud.storage.api import create_bucket
from gcloud.storage.api import get_all_buckets
from gcloud.storage.api import get_bucket
from gcloud.storage.api import lookup_bucket
Expand Down
34 changes: 34 additions & 0 deletions gcloud/storage/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,40 @@ def get_bucket(bucket_name, connection=None):
return Bucket(properties=response, connection=connection)


def create_bucket(bucket_name, connection=None):
"""Create a new bucket.
For example::
>>> from gcloud import storage
>>> storage.set_defaults()
>>> bucket = storage.create_bucket('my-bucket')
>>> print bucket
<Bucket: my-bucket>
This implements "storage.buckets.insert".
:type bucket_name: string
:param bucket_name: The bucket name to create.
:type connection: :class:`gcloud.storage.connection.Connection` or
``NoneType``
:param connection: Optional. The connection to use when sending requests.
If not provided, falls back to default.
:rtype: :class:`gcloud.storage.bucket.Bucket`
:returns: The newly created bucket.
:raises: :class:`gcloud.exceptions.Conflict` if
there is a confict (bucket already exists, invalid name, etc.)
"""
if connection is None:
connection = get_default_connection()

response = connection.api_request(method='POST', path='/b',
data={'name': bucket_name})
return Bucket(properties=response, connection=connection)


class _BucketIterator(Iterator):
"""An iterator listing all buckets.
Expand Down
36 changes: 2 additions & 34 deletions gcloud/storage/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,21 @@

from gcloud import connection as base_connection
from gcloud.exceptions import make_exception
from gcloud.storage.bucket import Bucket


class Connection(base_connection.Connection):
"""A connection to Google Cloud Storage via the JSON REST API.
This defines :meth:`Connection.api_request` for making a generic JSON
API request and most API requests are created elsewhere (e.g. in
API request and API requests are created elsewhere (e.g. in
:mod:`gcloud.storage.api` and
:class:`gcloud.storage.bucket.Bucket` and
:class:`gcloud.storage.blob.Blob`).
See :class:`gcloud.connection.Connection` for a full list of
parameters. This subclass differs only in needing a project
name (which you specify when creating a project in the Cloud
Console).
A typical use of this is to operate on
:class:`gcloud.storage.bucket.Bucket` objects::
>>> from gcloud import storage
>>> connection = storage.get_connection(project)
>>> bucket = connection.create_bucket('my-bucket-name')
"""

API_BASE_URL = base_connection.API_BASE_URL
Expand Down Expand Up @@ -245,28 +238,3 @@ def api_request(self, method, path, query_params=None,
return json.loads(content)

return content

def create_bucket(self, bucket_name):
"""Create a new bucket.
For example::
>>> from gcloud import storage
>>> connection = storage.get_connection(project)
>>> bucket = connection.create_bucket('my-bucket')
>>> print bucket
<Bucket: my-bucket>
This implements "storage.buckets.insert".
:type bucket_name: string
:param bucket_name: The bucket name to create.
:rtype: :class:`gcloud.storage.bucket.Bucket`
:returns: The newly created bucket.
:raises: :class:`gcloud.exceptions.Conflict` if
there is a confict (bucket already exists, invalid name, etc.)
"""
response = self.api_request(method='POST', path='/b',
data={'name': bucket_name})
return Bucket(properties=response, connection=self)
2 changes: 1 addition & 1 deletion gcloud/storage/demo/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Now let's create a new bucket...
bucket_name = ("bucket-%s" % time.time()).replace(".", "") # Get rid of dots.
print(bucket_name)
bucket = connection.create_bucket(bucket_name)
bucket = storage.create_bucket(bucket_name, connection=connection)
print(bucket)

# Let's look at all of the buckets again...
Expand Down
43 changes: 43 additions & 0 deletions gcloud/storage/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,49 @@ def test_hit_use_default(self):
self._get_bucket_hit_helper(use_default=True)


class Test_create_bucket(unittest2.TestCase):

def _callFUT(self, bucket_name, connection=None):
from gcloud.storage.api import create_bucket
return create_bucket(bucket_name, connection=connection)

def _create_bucket_success_helper(self, use_default=False):
from gcloud.storage._testing import _monkey_defaults
from gcloud.storage.connection import Connection
from gcloud.storage.bucket import Bucket
PROJECT = 'project'
BLOB_NAME = 'blob-name'
conn = Connection(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'},
'{"name": "%s"}' % BLOB_NAME,
)

if use_default:
with _monkey_defaults(connection=conn):
bucket = self._callFUT(BLOB_NAME)
else:
bucket = self._callFUT(BLOB_NAME, connection=conn)

self.assertTrue(isinstance(bucket, Bucket))
self.assertTrue(bucket.connection is conn)
self.assertEqual(bucket.name, BLOB_NAME)
self.assertEqual(http._called_with['method'], 'POST')
self.assertEqual(http._called_with['uri'], URI)

def test_success(self):
self._create_bucket_success_helper(use_default=False)

def test_success_use_default(self):
self._create_bucket_success_helper(use_default=True)


class Test__BucketIterator(unittest2.TestCase):

def _getTargetClass(self):
Expand Down
3 changes: 0 additions & 3 deletions gcloud/storage/test_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,6 @@ def api_request(self, method, path, query_params=None,
expect_json=True): # pragma: NO COVER
pass

def create_bucket(self, name): # pragma: NO COVER
pass


class _Response(dict):

Expand Down
22 changes: 0 additions & 22 deletions gcloud/storage/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,28 +281,6 @@ def test_api_request_w_500(self):
)
self.assertRaises(InternalServerError, conn.api_request, 'GET', '/')

def test_create_bucket_ok(self):
from gcloud.storage.bucket import Bucket
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'},
'{"name": "%s"}' % BLOB_NAME,
)
bucket = conn.create_bucket(BLOB_NAME)
self.assertTrue(isinstance(bucket, Bucket))
self.assertTrue(bucket.connection is conn)
self.assertEqual(bucket.name, BLOB_NAME)
self.assertEqual(http._called_with['method'], 'POST')
self.assertEqual(http._called_with['uri'], URI)


class Http(object):

Expand Down
6 changes: 3 additions & 3 deletions regression/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def setUpModule():
bucket_name = 'new%d' % (1000 * time.time(),)
# In the **very** rare case the bucket name is reserved, this
# fails with a ConnectionError.
SHARED_BUCKETS['test_bucket'] = CONNECTION.create_bucket(bucket_name)
SHARED_BUCKETS['test_bucket'] = storage.create_bucket(bucket_name)


def tearDownModule():
Expand All @@ -60,7 +60,7 @@ def test_create_bucket(self):
new_bucket_name = 'a-new-bucket'
self.assertRaises(exceptions.NotFound,
storage.get_bucket, new_bucket_name)
created = CONNECTION.create_bucket(new_bucket_name)
created = storage.create_bucket(new_bucket_name)
self.case_buckets_to_delete.append(new_bucket_name)
self.assertEqual(created.name, new_bucket_name)

Expand All @@ -72,7 +72,7 @@ def test_get_buckets(self):
]
created_buckets = []
for bucket_name in buckets_to_create:
bucket = CONNECTION.create_bucket(bucket_name)
bucket = storage.create_bucket(bucket_name)
self.case_buckets_to_delete.append(bucket_name)

# Retrieve the buckets.
Expand Down

0 comments on commit f21cacf

Please sign in to comment.