25
25
from gcloud .exceptions import NotFound
26
26
from gcloud .iterator import Iterator
27
27
from gcloud .storage ._helpers import _PropertyMixin
28
- from gcloud .storage ._helpers import _require_connection
29
28
from gcloud .storage ._helpers import _scalar_property
30
29
from gcloud .storage .acl import BucketACL
31
30
from gcloud .storage .acl import DefaultObjectACL
@@ -45,17 +44,18 @@ class _BlobIterator(Iterator):
45
44
:type extra_params: dict or None
46
45
:param extra_params: Extra query string parameters for the API call.
47
46
48
- :type connection : :class:`gcloud.storage.connection.Connection `
49
- :param connection: The connection to use when sending requests. Defaults
50
- to the bucket's connection
47
+ :type client : :class:`gcloud.storage.client.Client `
48
+ :param client: Optional. The client to use for making connections.
49
+ Defaults to the bucket's client.
51
50
"""
52
- def __init__ (self , bucket , extra_params = None , connection = None ):
53
- connection = _require_connection (connection )
51
+ def __init__ (self , bucket , extra_params = None , client = None ):
52
+ if client is None :
53
+ client = bucket .client
54
54
self .bucket = bucket
55
55
self .prefixes = set ()
56
56
self ._current_prefixes = None
57
57
super (_BlobIterator , self ).__init__ (
58
- connection = connection , path = bucket .path + '/o' ,
58
+ connection = client . connection , path = bucket .path + '/o' ,
59
59
extra_params = extra_params )
60
60
61
61
def get_items_from_response (self , response ):
@@ -76,6 +76,10 @@ def get_items_from_response(self, response):
76
76
class Bucket (_PropertyMixin ):
77
77
"""A class representing a Bucket on Cloud Storage.
78
78
79
+ :type client: :class:`gcloud.storage.client.Client`
80
+ :param client: A client which holds credentials and project configuration
81
+ for the bucket (which requires a project).
82
+
79
83
:type name: string
80
84
:param name: The name of the bucket.
81
85
"""
@@ -87,60 +91,57 @@ class Bucket(_PropertyMixin):
87
91
This is used in Bucket.delete() and Bucket.make_public().
88
92
"""
89
93
90
- def __init__ (self , name = None ):
94
+ def __init__ (self , client , name = None ):
91
95
super (Bucket , self ).__init__ (name = name )
96
+ self ._client = client
92
97
self ._acl = BucketACL (self )
93
98
self ._default_object_acl = DefaultObjectACL (self )
94
99
95
100
def __repr__ (self ):
96
101
return '<Bucket: %s>' % self .name
97
102
98
- @staticmethod
99
- def _client_or_connection (client ):
100
- """Temporary method to get a connection from a client.
101
-
102
- If the client is null, gets the connection from the environment.
103
+ def _require_client (self , client ):
104
+ """Check client or verify over-ride.
103
105
104
106
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
105
- :param client: Optional. The client to use. If not passed, falls back
106
- to default connection .
107
+ :param client: the client to use. If not passed, falls back to the
108
+ ``client`` stored on the current object .
107
109
108
- :rtype: :class:`gcloud.storage.connection.Connection `
109
- :returns: The connection determined from the ``client`` or environment .
110
+ :rtype: :class:`gcloud.storage.client.Client `
111
+ :returns: The client passed in or the currently bound client .
110
112
"""
111
113
if client is None :
112
- return _require_connection ()
113
- else :
114
- return client .connection
114
+ client = self .client
115
+ return client
115
116
116
117
def exists (self , client = None ):
117
118
"""Determines whether or not this bucket exists.
118
119
119
120
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
120
121
:param client: Optional. The client to use. If not passed, falls back
121
- to default connection .
122
+ to the ``client`` stored on the current bucket .
122
123
123
124
:rtype: boolean
124
125
:returns: True if the bucket exists in Cloud Storage.
125
126
"""
126
- connection = self ._client_or_connection (client )
127
+ client = self ._require_client (client )
127
128
try :
128
129
# We only need the status code (200 or not) so we seek to
129
130
# minimize the returned payload.
130
131
query_params = {'fields' : 'name' }
131
132
# We intentionally pass `_target_object=None` since fields=name
132
133
# would limit the local properties.
133
- connection .api_request (method = 'GET' , path = self .path ,
134
- query_params = query_params ,
135
- _target_object = None )
134
+ client . connection .api_request (method = 'GET' , path = self .path ,
135
+ query_params = query_params ,
136
+ _target_object = None )
136
137
# NOTE: This will not fail immediately in a batch. However, when
137
138
# Batch.finish() is called, the resulting `NotFound` will be
138
139
# raised.
139
140
return True
140
141
except NotFound :
141
142
return False
142
143
143
- def create (self , project = None , connection = None ):
144
+ def create (self , project = None , client = None ):
144
145
"""Creates current bucket.
145
146
146
147
If the bucket already exists, will raise
@@ -152,25 +153,24 @@ def create(self, project=None, connection=None):
152
153
:param project: Optional. The project to use when creating bucket.
153
154
If not provided, falls back to default.
154
155
155
- :type connection: :class:`gcloud.storage.connection.Connection` or
156
- ``NoneType``
157
- :param connection: Optional. The connection to use when sending
158
- requests. If not provided, falls back to default.
156
+ :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
157
+ :param client: Optional. The client to use. If not passed, falls back
158
+ to the ``client`` stored on the current bucket.
159
159
160
160
:rtype: :class:`gcloud.storage.bucket.Bucket`
161
161
:returns: The newly created bucket.
162
162
:raises: :class:`EnvironmentError` if the project is not given and
163
163
can't be inferred.
164
164
"""
165
- connection = _require_connection ( connection )
165
+ client = self . _require_client ( client )
166
166
if project is None :
167
167
project = get_default_project ()
168
168
if project is None :
169
169
raise EnvironmentError ('Project could not be inferred '
170
170
'from environment.' )
171
171
172
172
query_params = {'project' : project }
173
- api_response = connection .api_request (
173
+ api_response = client . connection .api_request (
174
174
method = 'POST' , path = '/b' , query_params = query_params ,
175
175
data = {'name' : self .name }, _target_object = self )
176
176
self ._set_properties (api_response )
@@ -205,6 +205,11 @@ def path(self):
205
205
206
206
return self .path_helper (self .name )
207
207
208
+ @property
209
+ def client (self ):
210
+ """The client bound to this bucket."""
211
+ return self ._client
212
+
208
213
def get_blob (self , blob_name , client = None ):
209
214
"""Get a blob object by name.
210
215
@@ -223,15 +228,15 @@ def get_blob(self, blob_name, client=None):
223
228
224
229
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
225
230
:param client: Optional. The client to use. If not passed, falls back
226
- to default connection .
231
+ to the ``client`` stored on the current bucket .
227
232
228
233
:rtype: :class:`gcloud.storage.blob.Blob` or None
229
234
:returns: The blob object if it exists, otherwise None.
230
235
"""
231
- connection = self ._client_or_connection (client )
236
+ client = self ._require_client (client )
232
237
blob = Blob (bucket = self , name = blob_name )
233
238
try :
234
- response = connection .api_request (
239
+ response = client . connection .api_request (
235
240
method = 'GET' , path = blob .path , _target_object = blob )
236
241
# NOTE: We assume response.get('name') matches `blob_name`.
237
242
blob ._set_properties (response )
@@ -244,7 +249,7 @@ def get_blob(self, blob_name, client=None):
244
249
245
250
def list_blobs (self , max_results = None , page_token = None , prefix = None ,
246
251
delimiter = None , versions = None ,
247
- projection = 'noAcl' , fields = None , connection = None ):
252
+ projection = 'noAcl' , fields = None , client = None ):
248
253
"""Return an iterator used to find blobs in the bucket.
249
254
250
255
:type max_results: integer or ``NoneType``
@@ -276,10 +281,9 @@ def list_blobs(self, max_results=None, page_token=None, prefix=None,
276
281
and the language of each blob returned:
277
282
'items/contentLanguage,nextPageToken'
278
283
279
- :type connection: :class:`gcloud.storage.connection.Connection` or
280
- ``NoneType``
281
- :param connection: Optional. The connection to use when sending
282
- requests. If not provided, falls back to default.
284
+ :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
285
+ :param client: Optional. The client to use. If not passed, falls back
286
+ to the ``client`` stored on the current bucket.
283
287
284
288
:rtype: :class:`_BlobIterator`.
285
289
:returns: An iterator of blobs.
@@ -304,7 +308,7 @@ def list_blobs(self, max_results=None, page_token=None, prefix=None,
304
308
extra_params ['fields' ] = fields
305
309
306
310
result = self ._iterator_class (
307
- self , extra_params = extra_params , connection = connection )
311
+ self , extra_params = extra_params , client = client )
308
312
# Page token must be handled specially since the base `Iterator`
309
313
# class has it as a reserved property.
310
314
if page_token is not None :
@@ -332,16 +336,16 @@ def delete(self, force=False, client=None):
332
336
333
337
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
334
338
:param client: Optional. The client to use. If not passed, falls back
335
- to default connection .
339
+ to the ``client`` stored on the current bucket .
336
340
337
341
:raises: :class:`ValueError` if ``force`` is ``True`` and the bucket
338
342
contains more than 256 objects / blobs.
339
343
"""
340
- connection = self ._client_or_connection (client )
344
+ client = self ._require_client (client )
341
345
if force :
342
346
blobs = list (self .list_blobs (
343
347
max_results = self ._MAX_OBJECTS_FOR_ITERATION + 1 ,
344
- connection = connection ))
348
+ client = client ))
345
349
if len (blobs ) > self ._MAX_OBJECTS_FOR_ITERATION :
346
350
message = (
347
351
'Refusing to delete bucket with more than '
@@ -358,8 +362,8 @@ def delete(self, force=False, client=None):
358
362
# We intentionally pass `_target_object=None` since a DELETE
359
363
# request has no response value (whether in a standard request or
360
364
# in a batch request).
361
- connection .api_request (method = 'DELETE' , path = self .path ,
362
- _target_object = None )
365
+ client . connection .api_request (method = 'DELETE' , path = self .path ,
366
+ _target_object = None )
363
367
364
368
def delete_blob (self , blob_name , client = None ):
365
369
"""Deletes a blob from the current bucket.
@@ -386,21 +390,21 @@ def delete_blob(self, blob_name, client=None):
386
390
387
391
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
388
392
:param client: Optional. The client to use. If not passed, falls back
389
- to default connection .
393
+ to the ``client`` stored on the current bucket .
390
394
391
395
:raises: :class:`gcloud.exceptions.NotFound` (to suppress
392
396
the exception, call ``delete_blobs``, passing a no-op
393
397
``on_error`` callback, e.g.::
394
398
395
399
>>> bucket.delete_blobs([blob], on_error=lambda blob: None)
396
400
"""
397
- connection = self ._client_or_connection (client )
401
+ client = self ._require_client (client )
398
402
blob_path = Blob .path_helper (self .path , blob_name )
399
403
# We intentionally pass `_target_object=None` since a DELETE
400
404
# request has no response value (whether in a standard request or
401
405
# in a batch request).
402
- connection .api_request (method = 'DELETE' , path = blob_path ,
403
- _target_object = None )
406
+ client . connection .api_request (method = 'DELETE' , path = blob_path ,
407
+ _target_object = None )
404
408
405
409
def delete_blobs (self , blobs , on_error = None , client = None ):
406
410
"""Deletes a list of blobs from the current bucket.
@@ -417,7 +421,7 @@ def delete_blobs(self, blobs, on_error=None, client=None):
417
421
418
422
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
419
423
:param client: Optional. The client to use. If not passed, falls back
420
- to default connection .
424
+ to the ``client`` stored on the current bucket .
421
425
422
426
:raises: :class:`gcloud.exceptions.NotFound` (if
423
427
`on_error` is not passed).
@@ -450,18 +454,18 @@ def copy_blob(self, blob, destination_bucket, new_name=None,
450
454
451
455
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
452
456
:param client: Optional. The client to use. If not passed, falls back
453
- to default connection .
457
+ to the ``client`` stored on the current bucket .
454
458
455
459
:rtype: :class:`gcloud.storage.blob.Blob`
456
460
:returns: The new Blob.
457
461
"""
458
- connection = self ._client_or_connection (client )
462
+ client = self ._require_client (client )
459
463
if new_name is None :
460
464
new_name = blob .name
461
465
new_blob = Blob (bucket = destination_bucket , name = new_name )
462
466
api_path = blob .path + '/copyTo' + new_blob .path
463
- copy_result = connection .api_request (method = 'POST' , path = api_path ,
464
- _target_object = new_blob )
467
+ copy_result = client . connection .api_request (
468
+ method = 'POST' , path = api_path , _target_object = new_blob )
465
469
new_blob ._set_properties (copy_result )
466
470
return new_blob
467
471
@@ -500,7 +504,7 @@ def upload_file(self, filename, blob_name=None, client=None):
500
504
501
505
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
502
506
:param client: Optional. The client to use. If not passed, falls back
503
- to default connection .
507
+ to the ``client`` stored on the current bucket .
504
508
505
509
:rtype: :class:`Blob`
506
510
:returns: The updated Blob object.
@@ -546,7 +550,7 @@ def upload_file_object(self, file_obj, blob_name=None, client=None):
546
550
547
551
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
548
552
:param client: Optional. The client to use. If not passed, falls back
549
- to default connection .
553
+ to the ``client`` stored on the current bucket .
550
554
551
555
:rtype: :class:`Blob`
552
556
:returns: The updated Blob object.
@@ -847,10 +851,8 @@ def make_public(self, recursive=False, future=False, client=None):
847
851
848
852
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
849
853
:param client: Optional. The client to use. If not passed, falls back
850
- to default connection .
854
+ to the ``client`` stored on the current bucket .
851
855
"""
852
- connection = self ._client_or_connection (client )
853
-
854
856
self .acl .all ().grant_read ()
855
857
self .acl .save (client = client )
856
858
@@ -865,7 +867,7 @@ def make_public(self, recursive=False, future=False, client=None):
865
867
blobs = list (self .list_blobs (
866
868
projection = 'full' ,
867
869
max_results = self ._MAX_OBJECTS_FOR_ITERATION + 1 ,
868
- connection = connection ))
870
+ client = client ))
869
871
if len (blobs ) > self ._MAX_OBJECTS_FOR_ITERATION :
870
872
message = (
871
873
'Refusing to make public recursively with more than '
0 commit comments