Skip to content

Commit

Permalink
Merge pull request #843 from dhermes/remove-connection-bucket
Browse files Browse the repository at this point in the history
Removing most remaining uses of self.connection in Bucket
  • Loading branch information
dhermes committed May 1, 2015
2 parents fb59514 + b282abb commit 8b6b4a2
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 71 deletions.
2 changes: 1 addition & 1 deletion gcloud/storage/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def create_bucket(bucket_name, project=None, connection=None):
"""
connection = _require_connection(connection)
bucket = Bucket(bucket_name, connection=connection)
bucket.create(project)
bucket.create(project, connection=connection)
return bucket


Expand Down
98 changes: 77 additions & 21 deletions gcloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
from gcloud._helpers import get_default_project
from gcloud.exceptions import NotFound
from gcloud.storage._helpers import _PropertyMixin
from gcloud.storage._helpers import _require_connection
from gcloud.storage._helpers import _scalar_property
from gcloud.storage.acl import BucketACL
from gcloud.storage.acl import DefaultObjectACL
Expand Down Expand Up @@ -114,23 +115,29 @@ def __contains__(self, blob_name):
blob = Blob(blob_name, bucket=self)
return blob.exists()

def exists(self):
def exists(self, connection=None):
"""Determines whether or not this bucket exists.
: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: boolean
:returns: True if the bucket exists in Cloud Storage.
"""
connection = _require_connection(connection)
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)
connection.api_request(method='GET', path=self.path,
query_params=query_params)
return True
except NotFound:
return False

def create(self, project=None):
def create(self, project=None, connection=None):
"""Creates current bucket.
If the bucket already exists, will raise
Expand All @@ -142,19 +149,25 @@ def create(self, project=None):
:param project: Optional. The project to use when creating bucket.
If not provided, falls back to default.
: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:`EnvironmentError` if the project is not given and
can't be inferred.
"""
connection = _require_connection(connection)
if project is None:
project = get_default_project()
if project is None:
raise EnvironmentError('Project could not be inferred '
'from environment.')

query_params = {'project': project}
api_response = self.connection.api_request(
api_response = connection.api_request(
method='POST', path='/b', query_params=query_params,
data={'name': self.name})
self._set_properties(api_response)
Expand Down Expand Up @@ -198,7 +211,7 @@ def path(self):

return self.path_helper(self.name)

def get_blob(self, blob_name):
def get_blob(self, blob_name, connection=None):
"""Get a blob object by name.
This will return None if the blob doesn't exist::
Expand All @@ -214,13 +227,19 @@ def get_blob(self, blob_name):
:type blob_name: string
:param blob_name: The name of the blob to retrieve.
: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.blob.Blob` or None
:returns: The blob object if it exists, otherwise None.
"""
connection = _require_connection(connection)
blob = Blob(bucket=self, name=blob_name)
try:
response = self.connection.api_request(method='GET',
path=blob.path)
response = connection.api_request(method='GET',
path=blob.path)
name = response.get('name') # Expect this to be blob_name
blob = Blob(name, bucket=self)
blob._set_properties(response)
Expand Down Expand Up @@ -291,7 +310,7 @@ def list_blobs(self, max_results=None, page_token=None, prefix=None,
result.next_page_token = page_token
return result

def delete(self, force=False):
def delete(self, force=False, connection=None):
"""Delete this bucket.
The bucket **must** be empty in order to submit a delete request. If
Expand All @@ -310,9 +329,15 @@ def delete(self, force=False):
:type force: boolean
:param force: If True, empties the bucket's objects then deletes it.
: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.
:raises: :class:`ValueError` if ``force`` is ``True`` and the bucket
contains more than 256 objects / blobs.
"""
connection = _require_connection(connection)
if force:
blobs = list(self.list_blobs(
max_results=self._MAX_OBJECTS_FOR_BUCKET_DELETE + 1))
Expand All @@ -326,11 +351,12 @@ def delete(self, force=False):
raise ValueError(message)

# Ignore 404 errors on delete.
self.delete_blobs(blobs, on_error=lambda blob: None)
self.delete_blobs(blobs, on_error=lambda blob: None,
connection=connection)

self.connection.api_request(method='DELETE', path=self.path)
connection.api_request(method='DELETE', path=self.path)

def delete_blob(self, blob_name):
def delete_blob(self, blob_name, connection=None):
"""Deletes a blob from the current bucket.
If the blob isn't found (backend 404), raises a
Expand All @@ -353,16 +379,22 @@ def delete_blob(self, blob_name):
:type blob_name: string
:param blob_name: A blob name to delete.
: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.
:raises: :class:`gcloud.exceptions.NotFound` (to suppress
the exception, call ``delete_blobs``, passing a no-op
``on_error`` callback, e.g.::
>>> bucket.delete_blobs([blob], on_error=lambda blob: None)
"""
connection = _require_connection(connection)
blob_path = Blob.path_helper(self.path, blob_name)
self.connection.api_request(method='DELETE', path=blob_path)
connection.api_request(method='DELETE', path=blob_path)

def delete_blobs(self, blobs, on_error=None):
def delete_blobs(self, blobs, on_error=None, connection=None):
"""Deletes a list of blobs from the current bucket.
Uses :func:`Bucket.delete_blob` to delete each individual blob.
Expand All @@ -375,22 +407,30 @@ def delete_blobs(self, blobs, on_error=None):
:class:`gcloud.exceptions.NotFound`;
otherwise, the exception is propagated.
: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.
:raises: :class:`gcloud.exceptions.NotFound` (if
`on_error` is not passed).
"""
connection = _require_connection(connection)
for blob in blobs:
try:
blob_name = blob
if not isinstance(blob_name, six.string_types):
blob_name = blob.name
self.delete_blob(blob_name)
self.delete_blob(blob_name, connection=connection)
except NotFound:
if on_error is not None:
on_error(blob)
else:
raise

def copy_blob(self, blob, destination_bucket, new_name=None):
@staticmethod
def copy_blob(blob, destination_bucket, new_name=None,
connection=None):
"""Copy the given blob to the given bucket, optionally with a new name.
:type blob: string or :class:`gcloud.storage.blob.Blob`
Expand All @@ -403,18 +443,24 @@ def copy_blob(self, blob, destination_bucket, new_name=None):
:type new_name: string
:param new_name: (optional) the new name for the copied file.
: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.blob.Blob`
:returns: The new Blob.
"""
connection = _require_connection(connection)
if new_name is None:
new_name = blob.name
new_blob = Blob(bucket=destination_bucket, name=new_name)
api_path = blob.path + '/copyTo' + new_blob.path
copy_result = self.connection.api_request(method='POST', path=api_path)
copy_result = connection.api_request(method='POST', path=api_path)
new_blob._set_properties(copy_result)
return new_blob

def upload_file(self, filename, blob_name=None):
def upload_file(self, filename, blob_name=None, connection=None):
"""Shortcut method to upload a file into this bucket.
Use this method to quickly put a local file in Cloud Storage.
Expand Down Expand Up @@ -447,16 +493,21 @@ def upload_file(self, filename, blob_name=None):
of the bucket with the same name as on your local
file system.
: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:`Blob`
:returns: The updated Blob object.
"""
if blob_name is None:
blob_name = os.path.basename(filename)
blob = Blob(bucket=self, name=blob_name)
blob.upload_from_filename(filename)
blob.upload_from_filename(filename, connection=connection)
return blob

def upload_file_object(self, file_obj, blob_name=None):
def upload_file_object(self, file_obj, blob_name=None, connection=None):
"""Shortcut method to upload a file object into this bucket.
Use this method to quickly put a local file in Cloud Storage.
Expand Down Expand Up @@ -489,13 +540,18 @@ def upload_file_object(self, file_obj, blob_name=None):
of the bucket with the same name as on your local
file system.
: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:`Blob`
:returns: The updated Blob object.
"""
if blob_name is None:
blob_name = os.path.basename(file_obj.name)
blob = Blob(bucket=self, name=blob_name)
blob.upload_from_file(file_obj)
blob.upload_from_file(file_obj, connection=connection)
return blob

@property
Expand Down
Loading

0 comments on commit 8b6b4a2

Please sign in to comment.