Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/cloud/storage/client.py: 23%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

347 statements  

1# Copyright 2015 Google LLC 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Client for interacting with the Google Cloud Storage API.""" 

16 

17import base64 

18import binascii 

19import collections 

20import datetime 

21import functools 

22import json 

23import warnings 

24import google.api_core.client_options 

25 

26from google.auth.credentials import AnonymousCredentials 

27 

28from google.api_core import page_iterator 

29from google.cloud._helpers import _LocalStack 

30from google.cloud.client import ClientWithProject 

31from google.cloud.exceptions import NotFound 

32 

33from google.cloud.storage._helpers import _add_generation_match_parameters 

34from google.cloud.storage._helpers import _bucket_bound_hostname_url 

35from google.cloud.storage._helpers import _get_api_endpoint_override 

36from google.cloud.storage._helpers import _get_environ_project 

37from google.cloud.storage._helpers import _get_storage_emulator_override 

38from google.cloud.storage._helpers import _use_client_cert 

39from google.cloud.storage._helpers import _virtual_hosted_style_base_url 

40from google.cloud.storage._helpers import _DEFAULT_UNIVERSE_DOMAIN 

41from google.cloud.storage._helpers import _DEFAULT_SCHEME 

42from google.cloud.storage._helpers import _STORAGE_HOST_TEMPLATE 

43from google.cloud.storage._helpers import _NOW 

44from google.cloud.storage._helpers import _UTC 

45from google.cloud.storage._opentelemetry_tracing import create_trace_span 

46 

47from google.cloud.storage._http import Connection 

48from google.cloud.storage._signing import ( 

49 get_expiration_seconds_v4, 

50 get_v4_now_dtstamps, 

51 ensure_signed_credentials, 

52 _sign_message, 

53) 

54from google.cloud.storage.batch import Batch 

55from google.cloud.storage.bucket import Bucket, _item_to_blob, _blobs_page_start 

56from google.cloud.storage.blob import Blob 

57from google.cloud.storage.hmac_key import HMACKeyMetadata 

58from google.cloud.storage.acl import BucketACL 

59from google.cloud.storage.acl import DefaultObjectACL 

60from google.cloud.storage.constants import _DEFAULT_TIMEOUT 

61from google.cloud.storage.retry import DEFAULT_RETRY 

62 

63 

64_marker = object() 

65 

66 

67class Client(ClientWithProject): 

68 """Client to bundle configuration needed for API requests. 

69 

70 :type project: str or None 

71 :param project: the project which the client acts on behalf of. Will be 

72 passed when creating a topic. If not passed, 

73 falls back to the default inferred from the environment. 

74 

75 :type credentials: :class:`~google.auth.credentials.Credentials` 

76 :param credentials: (Optional) The OAuth2 Credentials to use for this 

77 client. If not passed (and if no ``_http`` object is 

78 passed), falls back to the default inferred from the 

79 environment. 

80 

81 :type _http: :class:`~requests.Session` 

82 :param _http: (Optional) HTTP object to make requests. Can be any object 

83 that defines ``request()`` with the same interface as 

84 :meth:`requests.Session.request`. If not passed, an 

85 ``_http`` object is created that is bound to the 

86 ``credentials`` for the current object. 

87 This parameter should be considered private, and could 

88 change in the future. 

89 

90 :type client_info: :class:`~google.api_core.client_info.ClientInfo` 

91 :param client_info: 

92 The client info used to send a user-agent string along with API 

93 requests. If ``None``, then default info will be used. Generally, 

94 you only need to set this if you're developing your own library 

95 or partner tool. 

96 

97 :type client_options: :class:`~google.api_core.client_options.ClientOptions` or :class:`dict` 

98 :param client_options: (Optional) Client options used to set user options on the client. 

99 A non-default universe domain or api endpoint should be set through client_options. 

100 

101 :type use_auth_w_custom_endpoint: bool 

102 :param use_auth_w_custom_endpoint: 

103 (Optional) Whether authentication is required under custom endpoints. 

104 If false, uses AnonymousCredentials and bypasses authentication. 

105 Defaults to True. Note this is only used when a custom endpoint is set in conjunction. 

106 

107 :type extra_headers: dict 

108 :param extra_headers: 

109 (Optional) Custom headers to be sent with the requests attached to the client. 

110 For example, you can add custom audit logging headers. 

111 

112 :type api_key: string 

113 :param api_key: 

114 (Optional) An API key. Mutually exclusive with any other credentials. 

115 This parameter is an alias for setting `client_options.api_key` and 

116 will supercede any api key set in the `client_options` parameter. 

117 """ 

118 

119 SCOPE = ( 

120 "https://www.googleapis.com/auth/devstorage.full_control", 

121 "https://www.googleapis.com/auth/devstorage.read_only", 

122 "https://www.googleapis.com/auth/devstorage.read_write", 

123 ) 

124 """The scopes required for authenticating as a Cloud Storage consumer.""" 

125 

126 def __init__( 

127 self, 

128 project=_marker, 

129 credentials=None, 

130 _http=None, 

131 client_info=None, 

132 client_options=None, 

133 use_auth_w_custom_endpoint=True, 

134 extra_headers={}, 

135 *, 

136 api_key=None, 

137 ): 

138 self._base_connection = None 

139 

140 if project is None: 

141 no_project = True 

142 project = "<none>" 

143 else: 

144 no_project = False 

145 

146 if project is _marker: 

147 project = None 

148 

149 # Save the initial value of constructor arguments before they 

150 # are passed along, for use in __reduce__ defined elsewhere. 

151 self._initial_client_info = client_info 

152 self._initial_client_options = client_options 

153 self._extra_headers = extra_headers 

154 

155 connection_kw_args = {"client_info": client_info} 

156 

157 # api_key should set client_options.api_key. Set it here whether 

158 # client_options was specified as a dict, as a ClientOptions object, or 

159 # None. 

160 if api_key: 

161 if client_options and not isinstance(client_options, dict): 

162 client_options.api_key = api_key 

163 else: 

164 if not client_options: 

165 client_options = {} 

166 client_options["api_key"] = api_key 

167 

168 if client_options: 

169 if isinstance(client_options, dict): 

170 client_options = google.api_core.client_options.from_dict( 

171 client_options 

172 ) 

173 

174 if client_options and client_options.universe_domain: 

175 self._universe_domain = client_options.universe_domain 

176 else: 

177 self._universe_domain = None 

178 

179 storage_emulator_override = _get_storage_emulator_override() 

180 api_endpoint_override = _get_api_endpoint_override() 

181 

182 # Determine the api endpoint. The rules are as follows: 

183 

184 # 1. If the `api_endpoint` is set in `client_options`, use that as the 

185 # endpoint. 

186 if client_options and client_options.api_endpoint: 

187 api_endpoint = client_options.api_endpoint 

188 

189 # 2. Elif the "STORAGE_EMULATOR_HOST" env var is set, then use that as the 

190 # endpoint. 

191 elif storage_emulator_override: 

192 api_endpoint = storage_emulator_override 

193 

194 # 3. Elif the "API_ENDPOINT_OVERRIDE" env var is set, then use that as the 

195 # endpoint. 

196 elif api_endpoint_override: 

197 api_endpoint = api_endpoint_override 

198 

199 # 4. Elif the `universe_domain` is set in `client_options`, 

200 # create the endpoint using that as the default. 

201 # 

202 # Mutual TLS is not compatible with a non-default universe domain 

203 # at this time. If such settings are enabled along with the 

204 # "GOOGLE_API_USE_CLIENT_CERTIFICATE" env variable, a ValueError will 

205 # be raised. 

206 

207 elif self._universe_domain: 

208 # The final decision of whether to use mTLS takes place in 

209 # google-auth-library-python. We peek at the environment variable 

210 # here only to issue an exception in case of a conflict. 

211 if _use_client_cert(): 

212 raise ValueError( 

213 'The "GOOGLE_API_USE_CLIENT_CERTIFICATE" env variable is ' 

214 'set to "true" and a non-default universe domain is ' 

215 "configured. mTLS is not supported in any universe other than" 

216 "googleapis.com." 

217 ) 

218 api_endpoint = _DEFAULT_SCHEME + _STORAGE_HOST_TEMPLATE.format( 

219 universe_domain=self._universe_domain 

220 ) 

221 

222 # 5. Else, use the default, which is to use the default 

223 # universe domain of "googleapis.com" and create the endpoint 

224 # "storage.googleapis.com" from that. 

225 else: 

226 api_endpoint = None 

227 

228 connection_kw_args["api_endpoint"] = api_endpoint 

229 

230 self._is_emulator_set = True if storage_emulator_override else False 

231 

232 # If a custom endpoint is set, the client checks for credentials 

233 # or finds the default credentials based on the current environment. 

234 # Authentication may be bypassed under certain conditions: 

235 # (1) STORAGE_EMULATOR_HOST is set (for backwards compatibility), OR 

236 # (2) use_auth_w_custom_endpoint is set to False. 

237 if connection_kw_args["api_endpoint"] is not None: 

238 if self._is_emulator_set or not use_auth_w_custom_endpoint: 

239 if credentials is None: 

240 credentials = AnonymousCredentials() 

241 if project is None: 

242 project = _get_environ_project() 

243 if project is None: 

244 no_project = True 

245 project = "<none>" 

246 

247 super(Client, self).__init__( 

248 project=project, 

249 credentials=credentials, 

250 client_options=client_options, 

251 _http=_http, 

252 ) 

253 

254 # Validate that the universe domain of the credentials matches the 

255 # universe domain of the client. 

256 if self._credentials.universe_domain != self.universe_domain: 

257 raise ValueError( 

258 "The configured universe domain ({client_ud}) does not match " 

259 "the universe domain found in the credentials ({cred_ud}). If " 

260 "you haven't configured the universe domain explicitly, " 

261 "`googleapis.com` is the default.".format( 

262 client_ud=self.universe_domain, 

263 cred_ud=self._credentials.universe_domain, 

264 ) 

265 ) 

266 

267 if no_project: 

268 self.project = None 

269 

270 # Pass extra_headers to Connection 

271 connection = Connection(self, **connection_kw_args) 

272 connection.extra_headers = extra_headers 

273 self._connection = connection 

274 self._batch_stack = _LocalStack() 

275 

276 @classmethod 

277 def create_anonymous_client(cls): 

278 """Factory: return client with anonymous credentials. 

279 

280 .. note:: 

281 

282 Such a client has only limited access to "public" buckets: 

283 listing their contents and downloading their blobs. 

284 

285 :rtype: :class:`google.cloud.storage.client.Client` 

286 :returns: Instance w/ anonymous credentials and no project. 

287 """ 

288 client = cls(project="<none>", credentials=AnonymousCredentials()) 

289 client.project = None 

290 return client 

291 

292 @property 

293 def universe_domain(self): 

294 return self._universe_domain or _DEFAULT_UNIVERSE_DOMAIN 

295 

296 @property 

297 def api_endpoint(self): 

298 return self._connection.API_BASE_URL 

299 

300 @property 

301 def _connection(self): 

302 """Get connection or batch on the client. 

303 

304 :rtype: :class:`google.cloud.storage._http.Connection` 

305 :returns: The connection set on the client, or the batch 

306 if one is set. 

307 """ 

308 if self.current_batch is not None: 

309 return self.current_batch 

310 else: 

311 return self._base_connection 

312 

313 @_connection.setter 

314 def _connection(self, value): 

315 """Set connection on the client. 

316 

317 Intended to be used by constructor (since the base class calls) 

318 self._connection = connection 

319 Will raise if the connection is set more than once. 

320 

321 :type value: :class:`google.cloud.storage._http.Connection` 

322 :param value: The connection set on the client. 

323 

324 :raises: :class:`ValueError` if connection has already been set. 

325 """ 

326 if self._base_connection is not None: 

327 raise ValueError("Connection already set on client") 

328 self._base_connection = value 

329 

330 def _push_batch(self, batch): 

331 """Push a batch onto our stack. 

332 

333 "Protected", intended for use by batch context mgrs. 

334 

335 :type batch: :class:`google.cloud.storage.batch.Batch` 

336 :param batch: newly-active batch 

337 """ 

338 self._batch_stack.push(batch) 

339 

340 def _pop_batch(self): 

341 """Pop a batch from our stack. 

342 

343 "Protected", intended for use by batch context mgrs. 

344 

345 :raises: IndexError if the stack is empty. 

346 :rtype: :class:`google.cloud.storage.batch.Batch` 

347 :returns: the top-most batch/transaction, after removing it. 

348 """ 

349 return self._batch_stack.pop() 

350 

351 @property 

352 def current_batch(self): 

353 """Currently-active batch. 

354 

355 :rtype: :class:`google.cloud.storage.batch.Batch` or ``NoneType`` (if 

356 no batch is active). 

357 :returns: The batch at the top of the batch stack. 

358 """ 

359 return self._batch_stack.top 

360 

361 def get_service_account_email( 

362 self, project=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY 

363 ): 

364 """Get the email address of the project's GCS service account 

365 

366 :type project: str 

367 :param project: 

368 (Optional) Project ID to use for retreiving GCS service account 

369 email address. Defaults to the client's project. 

370 :type timeout: float or tuple 

371 :param timeout: 

372 (Optional) The amount of time, in seconds, to wait 

373 for the server response. See: :ref:`configuring_timeouts` 

374 

375 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

376 :param retry: 

377 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

378 

379 :rtype: str 

380 :returns: service account email address 

381 """ 

382 with create_trace_span(name="Storage.Client.getServiceAccountEmail"): 

383 if project is None: 

384 project = self.project 

385 

386 path = f"/projects/{project}/serviceAccount" 

387 api_response = self._get_resource(path, timeout=timeout, retry=retry) 

388 return api_response["email_address"] 

389 

390 def bucket(self, bucket_name, user_project=None, generation=None): 

391 """Factory constructor for bucket object. 

392 

393 .. note:: 

394 This will not make an HTTP request; it simply instantiates 

395 a bucket object owned by this client. 

396 

397 :type bucket_name: str 

398 :param bucket_name: The name of the bucket to be instantiated. 

399 

400 :type user_project: str 

401 :param user_project: (Optional) The project ID to be billed for API 

402 requests made via the bucket. 

403 

404 :type generation: int 

405 :param generation: (Optional) If present, selects a specific revision of 

406 this bucket. 

407 

408 :rtype: :class:`google.cloud.storage.bucket.Bucket` 

409 :returns: The bucket object created. 

410 """ 

411 return Bucket( 

412 client=self, 

413 name=bucket_name, 

414 user_project=user_project, 

415 generation=generation, 

416 ) 

417 

418 def batch(self, raise_exception=True): 

419 """Factory constructor for batch object. 

420 

421 .. note:: 

422 This will not make an HTTP request; it simply instantiates 

423 a batch object owned by this client. 

424 

425 :type raise_exception: bool 

426 :param raise_exception: 

427 (Optional) Defaults to True. If True, instead of adding exceptions 

428 to the list of return responses, the final exception will be raised. 

429 Note that exceptions are unwrapped after all operations are complete 

430 in success or failure, and only the last exception is raised. 

431 

432 :rtype: :class:`google.cloud.storage.batch.Batch` 

433 :returns: The batch object created. 

434 """ 

435 return Batch(client=self, raise_exception=raise_exception) 

436 

437 def _get_resource( 

438 self, 

439 path, 

440 query_params=None, 

441 headers=None, 

442 timeout=_DEFAULT_TIMEOUT, 

443 retry=DEFAULT_RETRY, 

444 _target_object=None, 

445 ): 

446 """Helper for bucket / blob methods making API 'GET' calls. 

447 

448 Args: 

449 path str: 

450 The path of the resource to fetch. 

451 

452 query_params Optional[dict]: 

453 HTTP query parameters to be passed 

454 

455 headers Optional[dict]: 

456 HTTP headers to be passed 

457 

458 timeout (Optional[Union[float, Tuple[float, float]]]): 

459 The amount of time, in seconds, to wait for the server response. 

460 

461 Can also be passed as a tuple (connect_timeout, read_timeout). 

462 See :meth:`requests.Session.request` documentation for details. 

463 

464 retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]): 

465 How to retry the RPC. A None value will disable retries. 

466 A google.api_core.retry.Retry value will enable retries, and the object will 

467 define retriable response codes and errors and configure backoff and timeout options. 

468 

469 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

470 activates it only if certain conditions are met. This class exists to provide safe defaults 

471 for RPC calls that are not technically safe to retry normally (due to potential data 

472 duplication or other side-effects) but become safe to retry if a condition such as 

473 if_metageneration_match is set. 

474 

475 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

476 information on retry types and how to configure them. 

477 

478 _target_object (Union[ \ 

479 :class:`~google.cloud.storage.bucket.Bucket`, \ 

480 :class:`~google.cloud.storage.bucket.blob`, \ 

481 ]): 

482 Object to which future data is to be applied -- only relevant 

483 in the context of a batch. 

484 

485 Returns: 

486 dict 

487 The JSON resource fetched 

488 

489 Raises: 

490 google.cloud.exceptions.NotFound 

491 If the bucket is not found. 

492 """ 

493 return self._connection.api_request( 

494 method="GET", 

495 path=path, 

496 query_params=query_params, 

497 headers=headers, 

498 timeout=timeout, 

499 retry=retry, 

500 _target_object=_target_object, 

501 ) 

502 

503 def _list_resource( 

504 self, 

505 path, 

506 item_to_value, 

507 page_token=None, 

508 max_results=None, 

509 extra_params=None, 

510 page_start=page_iterator._do_nothing_page_start, 

511 page_size=None, 

512 timeout=_DEFAULT_TIMEOUT, 

513 retry=DEFAULT_RETRY, 

514 ): 

515 kwargs = { 

516 "method": "GET", 

517 "path": path, 

518 "timeout": timeout, 

519 } 

520 with create_trace_span( 

521 name="Storage.Client._list_resource_returns_iterator", 

522 client=self, 

523 api_request=kwargs, 

524 retry=retry, 

525 ): 

526 api_request = functools.partial( 

527 self._connection.api_request, timeout=timeout, retry=retry 

528 ) 

529 return page_iterator.HTTPIterator( 

530 client=self, 

531 api_request=api_request, 

532 path=path, 

533 item_to_value=item_to_value, 

534 page_token=page_token, 

535 max_results=max_results, 

536 extra_params=extra_params, 

537 page_start=page_start, 

538 page_size=page_size, 

539 ) 

540 

541 def _patch_resource( 

542 self, 

543 path, 

544 data, 

545 query_params=None, 

546 headers=None, 

547 timeout=_DEFAULT_TIMEOUT, 

548 retry=None, 

549 _target_object=None, 

550 ): 

551 """Helper for bucket / blob methods making API 'PATCH' calls. 

552 

553 Args: 

554 path str: 

555 The path of the resource to fetch. 

556 

557 data dict: 

558 The data to be patched. 

559 

560 query_params Optional[dict]: 

561 HTTP query parameters to be passed 

562 

563 headers Optional[dict]: 

564 HTTP headers to be passed 

565 

566 timeout (Optional[Union[float, Tuple[float, float]]]): 

567 The amount of time, in seconds, to wait for the server response. 

568 

569 Can also be passed as a tuple (connect_timeout, read_timeout). 

570 See :meth:`requests.Session.request` documentation for details. 

571 

572 retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]): 

573 How to retry the RPC. A None value will disable retries. 

574 A google.api_core.retry.Retry value will enable retries, and the object will 

575 define retriable response codes and errors and configure backoff and timeout options. 

576 

577 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

578 activates it only if certain conditions are met. This class exists to provide safe defaults 

579 for RPC calls that are not technically safe to retry normally (due to potential data 

580 duplication or other side-effects) but become safe to retry if a condition such as 

581 if_metageneration_match is set. 

582 

583 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

584 information on retry types and how to configure them. 

585 

586 _target_object (Union[ \ 

587 :class:`~google.cloud.storage.bucket.Bucket`, \ 

588 :class:`~google.cloud.storage.bucket.blob`, \ 

589 ]): 

590 Object to which future data is to be applied -- only relevant 

591 in the context of a batch. 

592 

593 Returns: 

594 dict 

595 The JSON resource fetched 

596 

597 Raises: 

598 google.cloud.exceptions.NotFound 

599 If the bucket is not found. 

600 """ 

601 return self._connection.api_request( 

602 method="PATCH", 

603 path=path, 

604 data=data, 

605 query_params=query_params, 

606 headers=headers, 

607 timeout=timeout, 

608 retry=retry, 

609 _target_object=_target_object, 

610 ) 

611 

612 def _put_resource( 

613 self, 

614 path, 

615 data, 

616 query_params=None, 

617 headers=None, 

618 timeout=_DEFAULT_TIMEOUT, 

619 retry=None, 

620 _target_object=None, 

621 ): 

622 """Helper for bucket / blob methods making API 'PUT' calls. 

623 

624 Args: 

625 path str: 

626 The path of the resource to fetch. 

627 

628 data dict: 

629 The data to be patched. 

630 

631 query_params Optional[dict]: 

632 HTTP query parameters to be passed 

633 

634 headers Optional[dict]: 

635 HTTP headers to be passed 

636 

637 timeout (Optional[Union[float, Tuple[float, float]]]): 

638 The amount of time, in seconds, to wait for the server response. 

639 

640 Can also be passed as a tuple (connect_timeout, read_timeout). 

641 See :meth:`requests.Session.request` documentation for details. 

642 

643 retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]): 

644 How to retry the RPC. A None value will disable retries. 

645 A google.api_core.retry.Retry value will enable retries, and the object will 

646 define retriable response codes and errors and configure backoff and timeout options. 

647 

648 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

649 activates it only if certain conditions are met. This class exists to provide safe defaults 

650 for RPC calls that are not technically safe to retry normally (due to potential data 

651 duplication or other side-effects) but become safe to retry if a condition such as 

652 if_metageneration_match is set. 

653 

654 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

655 information on retry types and how to configure them. 

656 

657 _target_object (Union[ \ 

658 :class:`~google.cloud.storage.bucket.Bucket`, \ 

659 :class:`~google.cloud.storage.bucket.blob`, \ 

660 ]): 

661 Object to which future data is to be applied -- only relevant 

662 in the context of a batch. 

663 

664 Returns: 

665 dict 

666 The JSON resource fetched 

667 

668 Raises: 

669 google.cloud.exceptions.NotFound 

670 If the bucket is not found. 

671 """ 

672 return self._connection.api_request( 

673 method="PUT", 

674 path=path, 

675 data=data, 

676 query_params=query_params, 

677 headers=headers, 

678 timeout=timeout, 

679 retry=retry, 

680 _target_object=_target_object, 

681 ) 

682 

683 def _post_resource( 

684 self, 

685 path, 

686 data, 

687 query_params=None, 

688 headers=None, 

689 timeout=_DEFAULT_TIMEOUT, 

690 retry=None, 

691 _target_object=None, 

692 ): 

693 """Helper for bucket / blob methods making API 'POST' calls. 

694 

695 Args: 

696 path str: 

697 The path of the resource to which to post. 

698 

699 data dict: 

700 The data to be posted. 

701 

702 query_params Optional[dict]: 

703 HTTP query parameters to be passed 

704 

705 headers Optional[dict]: 

706 HTTP headers to be passed 

707 

708 timeout (Optional[Union[float, Tuple[float, float]]]): 

709 The amount of time, in seconds, to wait for the server response. 

710 

711 Can also be passed as a tuple (connect_timeout, read_timeout). 

712 See :meth:`requests.Session.request` documentation for details. 

713 

714 retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]): 

715 How to retry the RPC. A None value will disable retries. 

716 A google.api_core.retry.Retry value will enable retries, and the object will 

717 define retriable response codes and errors and configure backoff and timeout options. 

718 

719 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

720 activates it only if certain conditions are met. This class exists to provide safe defaults 

721 for RPC calls that are not technically safe to retry normally (due to potential data 

722 duplication or other side-effects) but become safe to retry if a condition such as 

723 if_metageneration_match is set. 

724 

725 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

726 information on retry types and how to configure them. 

727 

728 _target_object (Union[ \ 

729 :class:`~google.cloud.storage.bucket.Bucket`, \ 

730 :class:`~google.cloud.storage.bucket.blob`, \ 

731 ]): 

732 Object to which future data is to be applied -- only relevant 

733 in the context of a batch. 

734 

735 Returns: 

736 dict 

737 The JSON resource returned from the post. 

738 

739 Raises: 

740 google.cloud.exceptions.NotFound 

741 If the bucket is not found. 

742 """ 

743 

744 return self._connection.api_request( 

745 method="POST", 

746 path=path, 

747 data=data, 

748 query_params=query_params, 

749 headers=headers, 

750 timeout=timeout, 

751 retry=retry, 

752 _target_object=_target_object, 

753 ) 

754 

755 def _delete_resource( 

756 self, 

757 path, 

758 query_params=None, 

759 headers=None, 

760 timeout=_DEFAULT_TIMEOUT, 

761 retry=DEFAULT_RETRY, 

762 _target_object=None, 

763 ): 

764 """Helper for bucket / blob methods making API 'DELETE' calls. 

765 

766 Args: 

767 path str: 

768 The path of the resource to delete. 

769 

770 query_params Optional[dict]: 

771 HTTP query parameters to be passed 

772 

773 headers Optional[dict]: 

774 HTTP headers to be passed 

775 

776 timeout (Optional[Union[float, Tuple[float, float]]]): 

777 The amount of time, in seconds, to wait for the server response. 

778 

779 Can also be passed as a tuple (connect_timeout, read_timeout). 

780 See :meth:`requests.Session.request` documentation for details. 

781 

782 retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]): 

783 How to retry the RPC. A None value will disable retries. 

784 A google.api_core.retry.Retry value will enable retries, and the object will 

785 define retriable response codes and errors and configure backoff and timeout options. 

786 

787 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

788 activates it only if certain conditions are met. This class exists to provide safe defaults 

789 for RPC calls that are not technically safe to retry normally (due to potential data 

790 duplication or other side-effects) but become safe to retry if a condition such as 

791 if_metageneration_match is set. 

792 

793 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

794 information on retry types and how to configure them. 

795 

796 _target_object (Union[ \ 

797 :class:`~google.cloud.storage.bucket.Bucket`, \ 

798 :class:`~google.cloud.storage.bucket.blob`, \ 

799 ]): 

800 Object to which future data is to be applied -- only relevant 

801 in the context of a batch. 

802 

803 Returns: 

804 dict 

805 The JSON resource fetched 

806 

807 Raises: 

808 google.cloud.exceptions.NotFound 

809 If the bucket is not found. 

810 """ 

811 return self._connection.api_request( 

812 method="DELETE", 

813 path=path, 

814 query_params=query_params, 

815 headers=headers, 

816 timeout=timeout, 

817 retry=retry, 

818 _target_object=_target_object, 

819 ) 

820 

821 def _bucket_arg_to_bucket(self, bucket_or_name, generation=None): 

822 """Helper to return given bucket or create new by name. 

823 

824 Args: 

825 bucket_or_name (Union[ \ 

826 :class:`~google.cloud.storage.bucket.Bucket`, \ 

827 str, \ 

828 ]): 

829 The bucket resource to pass or name to create. 

830 generation (Optional[int]): 

831 The bucket generation. If generation is specified, 

832 bucket_or_name must be a name (str). 

833 

834 Returns: 

835 google.cloud.storage.bucket.Bucket 

836 The newly created bucket or the given one. 

837 """ 

838 if isinstance(bucket_or_name, Bucket): 

839 if generation: 

840 raise ValueError( 

841 "The generation can only be specified if a " 

842 "name is used to specify a bucket, not a Bucket object. " 

843 "Create a new Bucket object with the correct generation " 

844 "instead." 

845 ) 

846 bucket = bucket_or_name 

847 if bucket.client is None: 

848 bucket._client = self 

849 else: 

850 bucket = Bucket(self, name=bucket_or_name, generation=generation) 

851 return bucket 

852 

853 def get_bucket( 

854 self, 

855 bucket_or_name, 

856 timeout=_DEFAULT_TIMEOUT, 

857 if_metageneration_match=None, 

858 if_metageneration_not_match=None, 

859 retry=DEFAULT_RETRY, 

860 *, 

861 generation=None, 

862 soft_deleted=None, 

863 ): 

864 """Retrieve a bucket via a GET request. 

865 

866 See [API reference docs](https://cloud.google.com/storage/docs/json_api/v1/buckets/get) and a [code sample](https://cloud.google.com/storage/docs/samples/storage-get-bucket-metadata#storage_get_bucket_metadata-python). 

867 

868 Args: 

869 bucket_or_name (Union[ \ 

870 :class:`~google.cloud.storage.bucket.Bucket`, \ 

871 str, \ 

872 ]): 

873 The bucket resource to pass or name to create. 

874 

875 timeout (Optional[Union[float, Tuple[float, float]]]): 

876 The amount of time, in seconds, to wait for the server response. 

877 

878 Can also be passed as a tuple (connect_timeout, read_timeout). 

879 See :meth:`requests.Session.request` documentation for details. 

880 

881 if_metageneration_match (Optional[int]): 

882 Make the operation conditional on whether the 

883 bucket's current metageneration matches the given value. 

884 

885 if_metageneration_not_match (Optional[int]): 

886 Make the operation conditional on whether the bucket's 

887 current metageneration does not match the given value. 

888 

889 retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]): 

890 How to retry the RPC. A None value will disable retries. 

891 A google.api_core.retry.Retry value will enable retries, and the object will 

892 define retriable response codes and errors and configure backoff and timeout options. 

893 

894 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

895 activates it only if certain conditions are met. This class exists to provide safe defaults 

896 for RPC calls that are not technically safe to retry normally (due to potential data 

897 duplication or other side-effects) but become safe to retry if a condition such as 

898 if_metageneration_match is set. 

899 

900 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

901 information on retry types and how to configure them. 

902 

903 generation (Optional[int]): 

904 The generation of the bucket. The generation can be used to 

905 specify a specific soft-deleted version of the bucket, in 

906 conjunction with the ``soft_deleted`` argument below. If 

907 ``soft_deleted`` is not True, the generation is unused. 

908 

909 soft_deleted (Optional[bool]): 

910 If True, looks for a soft-deleted bucket. Will only return 

911 the bucket metadata if the bucket exists and is in a 

912 soft-deleted state. The bucket ``generation`` is required if 

913 ``soft_deleted`` is set to True. 

914 See: https://cloud.google.com/storage/docs/soft-delete 

915 

916 Returns: 

917 google.cloud.storage.bucket.Bucket 

918 The bucket matching the name provided. 

919 

920 Raises: 

921 google.cloud.exceptions.NotFound 

922 If the bucket is not found. 

923 """ 

924 with create_trace_span(name="Storage.Client.getBucket"): 

925 bucket = self._bucket_arg_to_bucket(bucket_or_name, generation=generation) 

926 bucket.reload( 

927 client=self, 

928 timeout=timeout, 

929 if_metageneration_match=if_metageneration_match, 

930 if_metageneration_not_match=if_metageneration_not_match, 

931 retry=retry, 

932 soft_deleted=soft_deleted, 

933 ) 

934 return bucket 

935 

936 def lookup_bucket( 

937 self, 

938 bucket_name, 

939 timeout=_DEFAULT_TIMEOUT, 

940 if_metageneration_match=None, 

941 if_metageneration_not_match=None, 

942 retry=DEFAULT_RETRY, 

943 ): 

944 """Get a bucket by name, returning None if not found. 

945 

946 You can use this if you would rather check for a None value 

947 than catching a NotFound exception. 

948 

949 :type bucket_name: str 

950 :param bucket_name: The name of the bucket to get. 

951 

952 :type timeout: float or tuple 

953 :param timeout: 

954 (Optional) The amount of time, in seconds, to wait 

955 for the server response. See: :ref:`configuring_timeouts` 

956 

957 :type if_metageneration_match: long 

958 :param if_metageneration_match: (Optional) Make the operation conditional on whether the 

959 blob's current metageneration matches the given value. 

960 

961 :type if_metageneration_not_match: long 

962 :param if_metageneration_not_match: (Optional) Make the operation conditional on whether the 

963 blob's current metageneration does not match the given value. 

964 

965 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

966 :param retry: 

967 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

968 

969 :rtype: :class:`google.cloud.storage.bucket.Bucket` or ``NoneType`` 

970 :returns: The bucket matching the name provided or None if not found. 

971 """ 

972 with create_trace_span(name="Storage.Client.lookupBucket"): 

973 try: 

974 return self.get_bucket( 

975 bucket_name, 

976 timeout=timeout, 

977 if_metageneration_match=if_metageneration_match, 

978 if_metageneration_not_match=if_metageneration_not_match, 

979 retry=retry, 

980 ) 

981 except NotFound: 

982 return None 

983 

984 def create_bucket( 

985 self, 

986 bucket_or_name, 

987 requester_pays=None, 

988 project=None, 

989 user_project=None, 

990 location=None, 

991 data_locations=None, 

992 predefined_acl=None, 

993 predefined_default_object_acl=None, 

994 enable_object_retention=False, 

995 timeout=_DEFAULT_TIMEOUT, 

996 retry=DEFAULT_RETRY, 

997 ): 

998 """Create a new bucket via a POST request. 

999 

1000 See [API reference docs](https://cloud.google.com/storage/docs/json_api/v1/buckets/insert) and a [code sample](https://cloud.google.com/storage/docs/samples/storage-create-bucket#storage_create_bucket-python). 

1001 

1002 Args: 

1003 bucket_or_name (Union[ \ 

1004 :class:`~google.cloud.storage.bucket.Bucket`, \ 

1005 str, \ 

1006 ]): 

1007 The bucket resource to pass or name to create. 

1008 requester_pays (bool): 

1009 DEPRECATED. Use Bucket().requester_pays instead. 

1010 (Optional) Whether requester pays for API requests for 

1011 this bucket and its blobs. 

1012 project (str): 

1013 (Optional) The project under which the bucket is to be created. 

1014 If not passed, uses the project set on the client. 

1015 user_project (str): 

1016 (Optional) The project ID to be billed for API requests 

1017 made via created bucket. 

1018 location (str): 

1019 (Optional) The location of the bucket. If not passed, 

1020 the default location, US, will be used. If specifying a dual-region, 

1021 `data_locations` should be set in conjunction. See: 

1022 https://cloud.google.com/storage/docs/locations 

1023 data_locations (list of str): 

1024 (Optional) The list of regional locations of a custom dual-region bucket. 

1025 Dual-regions require exactly 2 regional locations. See: 

1026 https://cloud.google.com/storage/docs/locations 

1027 predefined_acl (str): 

1028 (Optional) Name of predefined ACL to apply to bucket. See: 

1029 https://cloud.google.com/storage/docs/access-control/lists#predefined-acl 

1030 predefined_default_object_acl (str): 

1031 (Optional) Name of predefined ACL to apply to bucket's objects. See: 

1032 https://cloud.google.com/storage/docs/access-control/lists#predefined-acl 

1033 enable_object_retention (bool): 

1034 (Optional) Whether object retention should be enabled on this bucket. See: 

1035 https://cloud.google.com/storage/docs/object-lock 

1036 timeout (Optional[Union[float, Tuple[float, float]]]): 

1037 The amount of time, in seconds, to wait for the server response. 

1038 

1039 Can also be passed as a tuple (connect_timeout, read_timeout). 

1040 See :meth:`requests.Session.request` documentation for details. 

1041 

1042 retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]): 

1043 How to retry the RPC. A None value will disable retries. 

1044 A google.api_core.retry.Retry value will enable retries, and the object will 

1045 define retriable response codes and errors and configure backoff and timeout options. 

1046 

1047 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

1048 activates it only if certain conditions are met. This class exists to provide safe defaults 

1049 for RPC calls that are not technically safe to retry normally (due to potential data 

1050 duplication or other side-effects) but become safe to retry if a condition such as 

1051 if_metageneration_match is set. 

1052 

1053 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

1054 information on retry types and how to configure them. 

1055 

1056 Returns: 

1057 google.cloud.storage.bucket.Bucket 

1058 The newly created bucket. 

1059 

1060 Raises: 

1061 google.cloud.exceptions.Conflict 

1062 If the bucket already exists. 

1063 """ 

1064 with create_trace_span(name="Storage.Client.createBucket"): 

1065 bucket = self._bucket_arg_to_bucket(bucket_or_name) 

1066 query_params = {} 

1067 

1068 if project is None: 

1069 project = self.project 

1070 

1071 # Use no project if STORAGE_EMULATOR_HOST is set 

1072 if self._is_emulator_set: 

1073 if project is None: 

1074 project = _get_environ_project() 

1075 if project is None: 

1076 project = "<none>" 

1077 

1078 # Only include the project parameter if a project is set. 

1079 # If a project is not set, falls back to API validation (BadRequest). 

1080 if project is not None: 

1081 query_params = {"project": project} 

1082 

1083 if requester_pays is not None: 

1084 warnings.warn( 

1085 "requester_pays arg is deprecated. Use Bucket().requester_pays instead.", 

1086 PendingDeprecationWarning, 

1087 stacklevel=1, 

1088 ) 

1089 bucket.requester_pays = requester_pays 

1090 

1091 if predefined_acl is not None: 

1092 predefined_acl = BucketACL.validate_predefined(predefined_acl) 

1093 query_params["predefinedAcl"] = predefined_acl 

1094 

1095 if predefined_default_object_acl is not None: 

1096 predefined_default_object_acl = DefaultObjectACL.validate_predefined( 

1097 predefined_default_object_acl 

1098 ) 

1099 query_params[ 

1100 "predefinedDefaultObjectAcl" 

1101 ] = predefined_default_object_acl 

1102 

1103 if user_project is not None: 

1104 query_params["userProject"] = user_project 

1105 

1106 if enable_object_retention: 

1107 query_params["enableObjectRetention"] = enable_object_retention 

1108 

1109 properties = {key: bucket._properties[key] for key in bucket._changes} 

1110 properties["name"] = bucket.name 

1111 

1112 if location is not None: 

1113 properties["location"] = location 

1114 

1115 if data_locations is not None: 

1116 properties["customPlacementConfig"] = {"dataLocations": data_locations} 

1117 

1118 api_response = self._post_resource( 

1119 "/b", 

1120 properties, 

1121 query_params=query_params, 

1122 timeout=timeout, 

1123 retry=retry, 

1124 _target_object=bucket, 

1125 ) 

1126 

1127 bucket._set_properties(api_response) 

1128 return bucket 

1129 

1130 def download_blob_to_file( 

1131 self, 

1132 blob_or_uri, 

1133 file_obj, 

1134 start=None, 

1135 end=None, 

1136 raw_download=False, 

1137 if_etag_match=None, 

1138 if_etag_not_match=None, 

1139 if_generation_match=None, 

1140 if_generation_not_match=None, 

1141 if_metageneration_match=None, 

1142 if_metageneration_not_match=None, 

1143 timeout=_DEFAULT_TIMEOUT, 

1144 checksum="auto", 

1145 retry=DEFAULT_RETRY, 

1146 single_shot_download=False, 

1147 ): 

1148 """Download the contents of a blob object or blob URI into a file-like object. 

1149 

1150 See https://cloud.google.com/storage/docs/downloading-objects 

1151 

1152 Args: 

1153 blob_or_uri (Union[ \ 

1154 :class:`~google.cloud.storage.blob.Blob`, \ 

1155 str, \ 

1156 ]): 

1157 The blob resource to pass or URI to download. 

1158 

1159 file_obj (file): 

1160 A file handle to which to write the blob's data. 

1161 

1162 start (int): 

1163 (Optional) The first byte in a range to be downloaded. 

1164 

1165 end (int): 

1166 (Optional) The last byte in a range to be downloaded. 

1167 

1168 raw_download (bool): 

1169 (Optional) If true, download the object without any expansion. 

1170 

1171 if_etag_match (Union[str, Set[str]]): 

1172 (Optional) See :ref:`using-if-etag-match` 

1173 

1174 if_etag_not_match (Union[str, Set[str]]): 

1175 (Optional) See :ref:`using-if-etag-not-match` 

1176 

1177 if_generation_match (long): 

1178 (Optional) See :ref:`using-if-generation-match` 

1179 

1180 if_generation_not_match (long): 

1181 (Optional) See :ref:`using-if-generation-not-match` 

1182 

1183 if_metageneration_match (long): 

1184 (Optional) See :ref:`using-if-metageneration-match` 

1185 

1186 if_metageneration_not_match (long): 

1187 (Optional) See :ref:`using-if-metageneration-not-match` 

1188 

1189 timeout ([Union[float, Tuple[float, float]]]): 

1190 (Optional) The amount of time, in seconds, to wait 

1191 for the server response. See: :ref:`configuring_timeouts` 

1192 

1193 checksum (str): 

1194 (Optional) The type of checksum to compute to verify the integrity 

1195 of the object. The response headers must contain a checksum of the 

1196 requested type. If the headers lack an appropriate checksum (for 

1197 instance in the case of transcoded or ranged downloads where the 

1198 remote service does not know the correct checksum, including 

1199 downloads where chunk_size is set) an INFO-level log will be 

1200 emitted. Supported values are "md5", "crc32c", "auto" and None. 

1201 The default is "auto", which will try to detect if the C 

1202 extension for crc32c is installed and fall back to md5 otherwise. 

1203 

1204 retry (google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy) 

1205 (Optional) How to retry the RPC. A None value will disable 

1206 retries. A google.api_core.retry.Retry value will enable retries, 

1207 and the object will define retriable response codes and errors and 

1208 configure backoff and timeout options. 

1209 

1210 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a 

1211 Retry object and activates it only if certain conditions are met. 

1212 This class exists to provide safe defaults for RPC calls that are 

1213 not technically safe to retry normally (due to potential data 

1214 duplication or other side-effects) but become safe to retry if a 

1215 condition such as if_metageneration_match is set. 

1216 

1217 See the retry.py source code and docstrings in this package 

1218 (google.cloud.storage.retry) for information on retry types and how 

1219 to configure them. 

1220 

1221 single_shot_download (bool): 

1222 (Optional) If true, download the object in a single request. 

1223 """ 

1224 with create_trace_span(name="Storage.Client.downloadBlobToFile"): 

1225 if not isinstance(blob_or_uri, Blob): 

1226 blob_or_uri = Blob.from_uri(blob_or_uri) 

1227 

1228 blob_or_uri._prep_and_do_download( 

1229 file_obj, 

1230 client=self, 

1231 start=start, 

1232 end=end, 

1233 raw_download=raw_download, 

1234 if_etag_match=if_etag_match, 

1235 if_etag_not_match=if_etag_not_match, 

1236 if_generation_match=if_generation_match, 

1237 if_generation_not_match=if_generation_not_match, 

1238 if_metageneration_match=if_metageneration_match, 

1239 if_metageneration_not_match=if_metageneration_not_match, 

1240 timeout=timeout, 

1241 checksum=checksum, 

1242 retry=retry, 

1243 single_shot_download=single_shot_download, 

1244 ) 

1245 

1246 def list_blobs( 

1247 self, 

1248 bucket_or_name, 

1249 max_results=None, 

1250 page_token=None, 

1251 prefix=None, 

1252 delimiter=None, 

1253 start_offset=None, 

1254 end_offset=None, 

1255 include_trailing_delimiter=None, 

1256 versions=None, 

1257 projection="noAcl", 

1258 fields=None, 

1259 page_size=None, 

1260 timeout=_DEFAULT_TIMEOUT, 

1261 retry=DEFAULT_RETRY, 

1262 match_glob=None, 

1263 include_folders_as_prefixes=None, 

1264 soft_deleted=None, 

1265 ): 

1266 """Return an iterator used to find blobs in the bucket. 

1267 

1268 If :attr:`user_project` is set, bills the API request to that project. 

1269 

1270 .. note:: 

1271 List prefixes (directories) in a bucket using a prefix and delimiter. 

1272 See a [code sample](https://cloud.google.com/storage/docs/samples/storage-list-files-with-prefix#storage_list_files_with_prefix-python) 

1273 listing objects using a prefix filter. 

1274 

1275 Args: 

1276 bucket_or_name (Union[ \ 

1277 :class:`~google.cloud.storage.bucket.Bucket`, \ 

1278 str, \ 

1279 ]): 

1280 The bucket resource to pass or name to create. 

1281 

1282 max_results (int): 

1283 (Optional) The maximum number of blobs to return. 

1284 

1285 page_token (str): 

1286 (Optional) If present, return the next batch of blobs, using the 

1287 value, which must correspond to the ``nextPageToken`` value 

1288 returned in the previous response. Deprecated: use the ``pages`` 

1289 property of the returned iterator instead of manually passing the 

1290 token. 

1291 

1292 prefix (str): 

1293 (Optional) Prefix used to filter blobs. 

1294 

1295 delimiter (str): 

1296 (Optional) Delimiter, used with ``prefix`` to 

1297 emulate hierarchy. 

1298 

1299 start_offset (str): 

1300 (Optional) Filter results to objects whose names are 

1301 lexicographically equal to or after ``startOffset``. If 

1302 ``endOffset`` is also set, the objects listed will have names 

1303 between ``startOffset`` (inclusive) and ``endOffset`` 

1304 (exclusive). 

1305 

1306 end_offset (str): 

1307 (Optional) Filter results to objects whose names are 

1308 lexicographically before ``endOffset``. If ``startOffset`` is 

1309 also set, the objects listed will have names between 

1310 ``startOffset`` (inclusive) and ``endOffset`` (exclusive). 

1311 

1312 include_trailing_delimiter (boolean): 

1313 (Optional) If true, objects that end in exactly one instance of 

1314 ``delimiter`` will have their metadata included in ``items`` in 

1315 addition to ``prefixes``. 

1316 

1317 versions (bool): 

1318 (Optional) Whether object versions should be returned 

1319 as separate blobs. 

1320 

1321 projection (str): 

1322 (Optional) If used, must be 'full' or 'noAcl'. 

1323 Defaults to ``'noAcl'``. Specifies the set of 

1324 properties to return. 

1325 

1326 fields (str): 

1327 (Optional) Selector specifying which fields to include 

1328 in a partial response. Must be a list of fields. For 

1329 example to get a partial response with just the next 

1330 page token and the name and language of each blob returned: 

1331 ``'items(name,contentLanguage),nextPageToken'``. 

1332 See: https://cloud.google.com/storage/docs/json_api/v1/parameters#fields 

1333 

1334 page_size (int): 

1335 (Optional) Maximum number of blobs to return in each page. 

1336 Defaults to a value set by the API. 

1337 

1338 timeout (Optional[Union[float, Tuple[float, float]]]): 

1339 The amount of time, in seconds, to wait for the server response. 

1340 

1341 Can also be passed as a tuple (connect_timeout, read_timeout). 

1342 See :meth:`requests.Session.request` documentation for details. 

1343 

1344 retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]): 

1345 How to retry the RPC. A None value will disable retries. 

1346 A google.api_core.retry.Retry value will enable retries, and the object will 

1347 define retriable response codes and errors and configure backoff and timeout options. 

1348 

1349 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

1350 activates it only if certain conditions are met. This class exists to provide safe defaults 

1351 for RPC calls that are not technically safe to retry normally (due to potential data 

1352 duplication or other side-effects) but become safe to retry if a condition such as 

1353 if_metageneration_match is set. 

1354 

1355 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

1356 information on retry types and how to configure them. 

1357 

1358 match_glob (str): 

1359 (Optional) A glob pattern used to filter results (for example, foo*bar). 

1360 The string value must be UTF-8 encoded. See: 

1361 https://cloud.google.com/storage/docs/json_api/v1/objects/list#list-object-glob 

1362 

1363 include_folders_as_prefixes (bool): 

1364 (Optional) If true, includes Folders and Managed Folders in the set of 

1365 ``prefixes`` returned by the query. Only applicable if ``delimiter`` is set to /. 

1366 See: https://cloud.google.com/storage/docs/managed-folders 

1367 

1368 soft_deleted (bool): 

1369 (Optional) If true, only soft-deleted objects will be listed as distinct results in order of increasing 

1370 generation number. This parameter can only be used successfully if the bucket has a soft delete policy. 

1371 Note ``soft_deleted`` and ``versions`` cannot be set to True simultaneously. See: 

1372 https://cloud.google.com/storage/docs/soft-delete 

1373 

1374 Returns: 

1375 Iterator of all :class:`~google.cloud.storage.blob.Blob` 

1376 in this bucket matching the arguments. The RPC call 

1377 returns a response when the iterator is consumed. 

1378 

1379 As part of the response, you'll also get back an iterator.prefixes entity that lists object names 

1380 up to and including the requested delimiter. Duplicate entries are omitted from this list. 

1381 """ 

1382 with create_trace_span(name="Storage.Client.listBlobs"): 

1383 bucket = self._bucket_arg_to_bucket(bucket_or_name) 

1384 

1385 extra_params = {"projection": projection} 

1386 

1387 if prefix is not None: 

1388 extra_params["prefix"] = prefix 

1389 

1390 if delimiter is not None: 

1391 extra_params["delimiter"] = delimiter 

1392 

1393 if match_glob is not None: 

1394 extra_params["matchGlob"] = match_glob 

1395 

1396 if start_offset is not None: 

1397 extra_params["startOffset"] = start_offset 

1398 

1399 if end_offset is not None: 

1400 extra_params["endOffset"] = end_offset 

1401 

1402 if include_trailing_delimiter is not None: 

1403 extra_params["includeTrailingDelimiter"] = include_trailing_delimiter 

1404 

1405 if versions is not None: 

1406 extra_params["versions"] = versions 

1407 

1408 if fields is not None: 

1409 extra_params["fields"] = fields 

1410 

1411 if include_folders_as_prefixes is not None: 

1412 extra_params["includeFoldersAsPrefixes"] = include_folders_as_prefixes 

1413 

1414 if soft_deleted is not None: 

1415 extra_params["softDeleted"] = soft_deleted 

1416 

1417 if bucket.user_project is not None: 

1418 extra_params["userProject"] = bucket.user_project 

1419 

1420 path = bucket.path + "/o" 

1421 iterator = self._list_resource( 

1422 path, 

1423 _item_to_blob, 

1424 page_token=page_token, 

1425 max_results=max_results, 

1426 extra_params=extra_params, 

1427 page_start=_blobs_page_start, 

1428 page_size=page_size, 

1429 timeout=timeout, 

1430 retry=retry, 

1431 ) 

1432 iterator.bucket = bucket 

1433 iterator.prefixes = set() 

1434 return iterator 

1435 

1436 def list_buckets( 

1437 self, 

1438 max_results=None, 

1439 page_token=None, 

1440 prefix=None, 

1441 projection="noAcl", 

1442 fields=None, 

1443 project=None, 

1444 page_size=None, 

1445 timeout=_DEFAULT_TIMEOUT, 

1446 retry=DEFAULT_RETRY, 

1447 *, 

1448 soft_deleted=None, 

1449 ): 

1450 """Get all buckets in the project associated to the client. 

1451 

1452 This will not populate the list of blobs available in each 

1453 bucket. 

1454 

1455 See [API reference docs](https://cloud.google.com/storage/docs/json_api/v1/buckets/list) and a [code sample](https://cloud.google.com/storage/docs/samples/storage-list-buckets#storage_list_buckets-python). 

1456 

1457 :type max_results: int 

1458 :param max_results: (Optional) The maximum number of buckets to return. 

1459 

1460 :type page_token: str 

1461 :param page_token: 

1462 (Optional) If present, return the next batch of buckets, using the 

1463 value, which must correspond to the ``nextPageToken`` value 

1464 returned in the previous response. Deprecated: use the ``pages`` 

1465 property of the returned iterator instead of manually passing the 

1466 token. 

1467 

1468 :type prefix: str 

1469 :param prefix: (Optional) Filter results to buckets whose names begin 

1470 with this prefix. 

1471 

1472 :type projection: str 

1473 :param projection: 

1474 (Optional) Specifies the set of properties to return. If used, must 

1475 be 'full' or 'noAcl'. Defaults to 'noAcl'. 

1476 

1477 :type fields: str 

1478 :param fields: 

1479 (Optional) Selector specifying which fields to include in a partial 

1480 response. Must be a list of fields. For example to get a partial 

1481 response with just the next page token and the language of each 

1482 bucket returned: 'items/id,nextPageToken' 

1483 

1484 :type project: str 

1485 :param project: (Optional) The project whose buckets are to be listed. 

1486 If not passed, uses the project set on the client. 

1487 

1488 :type page_size: int 

1489 :param page_size: (Optional) Maximum number of buckets to return in each page. 

1490 Defaults to a value set by the API. 

1491 

1492 :type timeout: float or tuple 

1493 :param timeout: 

1494 (Optional) The amount of time, in seconds, to wait 

1495 for the server response. See: :ref:`configuring_timeouts` 

1496 

1497 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

1498 :param retry: 

1499 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

1500 

1501 :type soft_deleted: bool 

1502 :param soft_deleted: 

1503 (Optional) If true, only soft-deleted buckets will be listed as distinct results in order of increasing 

1504 generation number. This parameter can only be used successfully if the bucket has a soft delete policy. 

1505 See: https://cloud.google.com/storage/docs/soft-delete 

1506 

1507 :rtype: :class:`~google.api_core.page_iterator.Iterator` 

1508 :raises ValueError: if both ``project`` is ``None`` and the client's 

1509 project is also ``None``. 

1510 :returns: Iterator of all :class:`~google.cloud.storage.bucket.Bucket` 

1511 belonging to this project. 

1512 """ 

1513 with create_trace_span(name="Storage.Client.listBuckets"): 

1514 extra_params = {} 

1515 

1516 if project is None: 

1517 project = self.project 

1518 

1519 # Use no project if STORAGE_EMULATOR_HOST is set 

1520 if self._is_emulator_set: 

1521 if project is None: 

1522 project = _get_environ_project() 

1523 if project is None: 

1524 project = "<none>" 

1525 

1526 # Only include the project parameter if a project is set. 

1527 # If a project is not set, falls back to API validation (BadRequest). 

1528 if project is not None: 

1529 extra_params = {"project": project} 

1530 

1531 if prefix is not None: 

1532 extra_params["prefix"] = prefix 

1533 

1534 extra_params["projection"] = projection 

1535 

1536 if fields is not None: 

1537 extra_params["fields"] = fields 

1538 

1539 if soft_deleted is not None: 

1540 extra_params["softDeleted"] = soft_deleted 

1541 

1542 return self._list_resource( 

1543 "/b", 

1544 _item_to_bucket, 

1545 page_token=page_token, 

1546 max_results=max_results, 

1547 extra_params=extra_params, 

1548 page_size=page_size, 

1549 timeout=timeout, 

1550 retry=retry, 

1551 ) 

1552 

1553 def restore_bucket( 

1554 self, 

1555 bucket_name, 

1556 generation, 

1557 projection="noAcl", 

1558 if_metageneration_match=None, 

1559 if_metageneration_not_match=None, 

1560 timeout=_DEFAULT_TIMEOUT, 

1561 retry=DEFAULT_RETRY, 

1562 ): 

1563 """Restores a soft-deleted bucket. 

1564 

1565 :type bucket_name: str 

1566 :param bucket_name: The name of the bucket to be restored. 

1567 

1568 :type generation: int 

1569 :param generation: Selects the specific revision of the bucket. 

1570 

1571 :type projection: str 

1572 :param projection: 

1573 (Optional) Specifies the set of properties to return. If used, must 

1574 be 'full' or 'noAcl'. Defaults to 'noAcl'. 

1575 

1576 if_metageneration_match (Optional[int]): 

1577 Make the operation conditional on whether the 

1578 blob's current metageneration matches the given value. 

1579 

1580 if_metageneration_not_match (Optional[int]): 

1581 Make the operation conditional on whether the blob's 

1582 current metageneration does not match the given value. 

1583 

1584 :type timeout: float or tuple 

1585 :param timeout: 

1586 (Optional) The amount of time, in seconds, to wait 

1587 for the server response. See: :ref:`configuring_timeouts` 

1588 

1589 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

1590 :param retry: 

1591 (Optional) How to retry the RPC. 

1592 

1593 Users can configure non-default retry behavior. A ``None`` value will 

1594 disable retries. See [Configuring Retries](https://cloud.google.com/python/docs/reference/storage/latest/retry_timeout). 

1595 

1596 :rtype: :class:`google.cloud.storage.bucket.Bucket` 

1597 :returns: The restored Bucket. 

1598 """ 

1599 query_params = {"generation": generation, "projection": projection} 

1600 

1601 _add_generation_match_parameters( 

1602 query_params, 

1603 if_metageneration_match=if_metageneration_match, 

1604 if_metageneration_not_match=if_metageneration_not_match, 

1605 ) 

1606 

1607 bucket = self.bucket(bucket_name) 

1608 api_response = self._post_resource( 

1609 f"{bucket.path}/restore", 

1610 None, 

1611 query_params=query_params, 

1612 timeout=timeout, 

1613 retry=retry, 

1614 ) 

1615 bucket._set_properties(api_response) 

1616 return bucket 

1617 

1618 def create_hmac_key( 

1619 self, 

1620 service_account_email, 

1621 project_id=None, 

1622 user_project=None, 

1623 timeout=_DEFAULT_TIMEOUT, 

1624 retry=None, 

1625 ): 

1626 """Create an HMAC key for a service account. 

1627 

1628 :type service_account_email: str 

1629 :param service_account_email: e-mail address of the service account 

1630 

1631 :type project_id: str 

1632 :param project_id: (Optional) Explicit project ID for the key. 

1633 Defaults to the client's project. 

1634 

1635 :type user_project: str 

1636 :param user_project: (Optional) This parameter is currently ignored. 

1637 

1638 :type timeout: float or tuple 

1639 :param timeout: 

1640 (Optional) The amount of time, in seconds, to wait 

1641 for the server response. See: :ref:`configuring_timeouts` 

1642 

1643 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

1644 :param retry: (Optional) How to retry the RPC. A None value will disable retries. 

1645 A google.api_core.retry.Retry value will enable retries, and the object will 

1646 define retriable response codes and errors and configure backoff and timeout options. 

1647 

1648 A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and 

1649 activates it only if certain conditions are met. This class exists to provide safe defaults 

1650 for RPC calls that are not technically safe to retry normally (due to potential data 

1651 duplication or other side-effects) but become safe to retry if a condition such as 

1652 if_metageneration_match is set. 

1653 

1654 See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for 

1655 information on retry types and how to configure them. 

1656 

1657 :rtype: 

1658 Tuple[:class:`~google.cloud.storage.hmac_key.HMACKeyMetadata`, str] 

1659 :returns: metadata for the created key, plus the bytes of the key's secret, which is an 40-character base64-encoded string. 

1660 """ 

1661 with create_trace_span(name="Storage.Client.createHmacKey"): 

1662 if project_id is None: 

1663 project_id = self.project 

1664 

1665 path = f"/projects/{project_id}/hmacKeys" 

1666 qs_params = {"serviceAccountEmail": service_account_email} 

1667 

1668 if user_project is not None: 

1669 qs_params["userProject"] = user_project 

1670 

1671 api_response = self._post_resource( 

1672 path, 

1673 None, 

1674 query_params=qs_params, 

1675 timeout=timeout, 

1676 retry=retry, 

1677 ) 

1678 metadata = HMACKeyMetadata(self) 

1679 metadata._properties = api_response["metadata"] 

1680 secret = api_response["secret"] 

1681 return metadata, secret 

1682 

1683 def list_hmac_keys( 

1684 self, 

1685 max_results=None, 

1686 service_account_email=None, 

1687 show_deleted_keys=None, 

1688 project_id=None, 

1689 user_project=None, 

1690 timeout=_DEFAULT_TIMEOUT, 

1691 retry=DEFAULT_RETRY, 

1692 ): 

1693 """List HMAC keys for a project. 

1694 

1695 :type max_results: int 

1696 :param max_results: 

1697 (Optional) Max number of keys to return in a given page. 

1698 

1699 :type service_account_email: str 

1700 :param service_account_email: 

1701 (Optional) Limit keys to those created by the given service account. 

1702 

1703 :type show_deleted_keys: bool 

1704 :param show_deleted_keys: 

1705 (Optional) Included deleted keys in the list. Default is to 

1706 exclude them. 

1707 

1708 :type project_id: str 

1709 :param project_id: (Optional) Explicit project ID for the key. 

1710 Defaults to the client's project. 

1711 

1712 :type user_project: str 

1713 :param user_project: (Optional) This parameter is currently ignored. 

1714 

1715 :type timeout: float or tuple 

1716 :param timeout: 

1717 (Optional) The amount of time, in seconds, to wait 

1718 for the server response. See: :ref:`configuring_timeouts` 

1719 

1720 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

1721 :param retry: 

1722 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

1723 

1724 :rtype: 

1725 Tuple[:class:`~google.cloud.storage.hmac_key.HMACKeyMetadata`, str] 

1726 :returns: metadata for the created key, plus the bytes of the key's secret, which is an 40-character base64-encoded string. 

1727 """ 

1728 with create_trace_span(name="Storage.Client.listHmacKeys"): 

1729 if project_id is None: 

1730 project_id = self.project 

1731 

1732 path = f"/projects/{project_id}/hmacKeys" 

1733 extra_params = {} 

1734 

1735 if service_account_email is not None: 

1736 extra_params["serviceAccountEmail"] = service_account_email 

1737 

1738 if show_deleted_keys is not None: 

1739 extra_params["showDeletedKeys"] = show_deleted_keys 

1740 

1741 if user_project is not None: 

1742 extra_params["userProject"] = user_project 

1743 

1744 return self._list_resource( 

1745 path, 

1746 _item_to_hmac_key_metadata, 

1747 max_results=max_results, 

1748 extra_params=extra_params, 

1749 timeout=timeout, 

1750 retry=retry, 

1751 ) 

1752 

1753 def get_hmac_key_metadata( 

1754 self, access_id, project_id=None, user_project=None, timeout=_DEFAULT_TIMEOUT 

1755 ): 

1756 """Return a metadata instance for the given HMAC key. 

1757 

1758 :type access_id: str 

1759 :param access_id: Unique ID of an existing key. 

1760 

1761 :type project_id: str 

1762 :param project_id: (Optional) Project ID of an existing key. 

1763 Defaults to client's project. 

1764 

1765 :type timeout: float or tuple 

1766 :param timeout: 

1767 (Optional) The amount of time, in seconds, to wait 

1768 for the server response. See: :ref:`configuring_timeouts` 

1769 

1770 :type user_project: str 

1771 :param user_project: (Optional) This parameter is currently ignored. 

1772 """ 

1773 with create_trace_span(name="Storage.Client.getHmacKeyMetadata"): 

1774 metadata = HMACKeyMetadata(self, access_id, project_id, user_project) 

1775 metadata.reload(timeout=timeout) # raises NotFound for missing key 

1776 return metadata 

1777 

1778 def generate_signed_post_policy_v4( 

1779 self, 

1780 bucket_name, 

1781 blob_name, 

1782 expiration, 

1783 conditions=None, 

1784 fields=None, 

1785 credentials=None, 

1786 virtual_hosted_style=False, 

1787 bucket_bound_hostname=None, 

1788 scheme="http", 

1789 service_account_email=None, 

1790 access_token=None, 

1791 ): 

1792 """Generate a V4 signed policy object. Generated policy object allows user to upload objects with a POST request. 

1793 

1794 .. note:: 

1795 

1796 Assumes ``credentials`` implements the 

1797 :class:`google.auth.credentials.Signing` interface. Also assumes 

1798 ``credentials`` has a ``service_account_email`` property which 

1799 identifies the credentials. 

1800 

1801 See a [code sample](https://github.com/googleapis/python-storage/blob/main/samples/snippets/storage_generate_signed_post_policy_v4.py). 

1802 

1803 :type bucket_name: str 

1804 :param bucket_name: Bucket name. 

1805 

1806 :type blob_name: str 

1807 :param blob_name: Object name. 

1808 

1809 :type expiration: Union[Integer, datetime.datetime, datetime.timedelta] 

1810 :param expiration: Policy expiration time. If a ``datetime`` instance is 

1811 passed without an explicit ``tzinfo`` set, it will be 

1812 assumed to be ``UTC``. 

1813 

1814 :type conditions: list 

1815 :param conditions: (Optional) List of POST policy conditions, which are 

1816 used to restrict what is allowed in the request. 

1817 

1818 :type fields: dict 

1819 :param fields: (Optional) Additional elements to include into request. 

1820 

1821 :type credentials: :class:`google.auth.credentials.Signing` 

1822 :param credentials: (Optional) Credentials object with an associated private 

1823 key to sign text. 

1824 

1825 :type virtual_hosted_style: bool 

1826 :param virtual_hosted_style: 

1827 (Optional) If True, construct the URL relative to the bucket 

1828 virtual hostname, e.g., '<bucket-name>.storage.googleapis.com'. 

1829 Incompatible with bucket_bound_hostname. 

1830 

1831 :type bucket_bound_hostname: str 

1832 :param bucket_bound_hostname: 

1833 (Optional) If passed, construct the URL relative to the bucket-bound hostname. 

1834 Value can be bare or with a scheme, e.g., 'example.com' or 'http://example.com'. 

1835 Incompatible with virtual_hosted_style. 

1836 See: https://cloud.google.com/storage/docs/request-endpoints#cname 

1837 

1838 :type scheme: str 

1839 :param scheme: 

1840 (Optional) If ``bucket_bound_hostname`` is passed as a bare hostname, use 

1841 this value as a scheme. ``https`` will work only when using a CDN. 

1842 Defaults to ``"http"``. 

1843 

1844 :type service_account_email: str 

1845 :param service_account_email: (Optional) E-mail address of the service account. 

1846 

1847 :type access_token: str 

1848 :param access_token: (Optional) Access token for a service account. 

1849 

1850 :raises: :exc:`ValueError` when mutually exclusive arguments are used. 

1851 

1852 :rtype: dict 

1853 :returns: Signed POST policy. 

1854 """ 

1855 if virtual_hosted_style and bucket_bound_hostname: 

1856 raise ValueError( 

1857 "Only one of virtual_hosted_style and bucket_bound_hostname " 

1858 "can be specified." 

1859 ) 

1860 

1861 credentials = self._credentials if credentials is None else credentials 

1862 client_email = service_account_email 

1863 if not access_token or not service_account_email: 

1864 ensure_signed_credentials(credentials) 

1865 client_email = credentials.signer_email 

1866 

1867 # prepare policy conditions and fields 

1868 timestamp, datestamp = get_v4_now_dtstamps() 

1869 

1870 x_goog_credential = "{email}/{datestamp}/auto/storage/goog4_request".format( 

1871 email=client_email, datestamp=datestamp 

1872 ) 

1873 required_conditions = [ 

1874 {"bucket": bucket_name}, 

1875 {"key": blob_name}, 

1876 {"x-goog-date": timestamp}, 

1877 {"x-goog-credential": x_goog_credential}, 

1878 {"x-goog-algorithm": "GOOG4-RSA-SHA256"}, 

1879 ] 

1880 

1881 conditions = conditions or [] 

1882 policy_fields = {} 

1883 for key, value in sorted((fields or {}).items()): 

1884 if not key.startswith("x-ignore-"): 

1885 policy_fields[key] = value 

1886 conditions.append({key: value}) 

1887 

1888 conditions += required_conditions 

1889 

1890 # calculate policy expiration time 

1891 now = _NOW(_UTC).replace(tzinfo=None) 

1892 if expiration is None: 

1893 expiration = now + datetime.timedelta(hours=1) 

1894 

1895 policy_expires = now + datetime.timedelta( 

1896 seconds=get_expiration_seconds_v4(expiration) 

1897 ) 

1898 

1899 # encode policy for signing 

1900 policy = json.dumps( 

1901 collections.OrderedDict( 

1902 sorted( 

1903 { 

1904 "conditions": conditions, 

1905 "expiration": policy_expires.isoformat() + "Z", 

1906 }.items() 

1907 ) 

1908 ), 

1909 separators=(",", ":"), 

1910 ) 

1911 str_to_sign = base64.b64encode(policy.encode("utf-8")) 

1912 

1913 # sign the policy and get its cryptographic signature 

1914 if access_token and service_account_email: 

1915 signature = _sign_message(str_to_sign, access_token, service_account_email) 

1916 signature_bytes = base64.b64decode(signature) 

1917 else: 

1918 signature_bytes = credentials.sign_bytes(str_to_sign) 

1919 

1920 # get hexadecimal representation of the signature 

1921 signature = binascii.hexlify(signature_bytes).decode("utf-8") 

1922 

1923 policy_fields.update( 

1924 { 

1925 "key": blob_name, 

1926 "x-goog-algorithm": "GOOG4-RSA-SHA256", 

1927 "x-goog-credential": x_goog_credential, 

1928 "x-goog-date": timestamp, 

1929 "x-goog-signature": signature, 

1930 "policy": str_to_sign.decode("utf-8"), 

1931 } 

1932 ) 

1933 # designate URL 

1934 if virtual_hosted_style: 

1935 url = _virtual_hosted_style_base_url( 

1936 self.api_endpoint, bucket_name, trailing_slash=True 

1937 ) 

1938 elif bucket_bound_hostname: 

1939 url = f"{_bucket_bound_hostname_url(bucket_bound_hostname, scheme)}/" 

1940 else: 

1941 url = f"{self.api_endpoint}/{bucket_name}/" 

1942 

1943 return {"url": url, "fields": policy_fields} 

1944 

1945 

1946def _item_to_bucket(iterator, item): 

1947 """Convert a JSON bucket to the native object. 

1948 

1949 :type iterator: :class:`~google.api_core.page_iterator.Iterator` 

1950 :param iterator: The iterator that has retrieved the item. 

1951 

1952 :type item: dict 

1953 :param item: An item to be converted to a bucket. 

1954 

1955 :rtype: :class:`.Bucket` 

1956 :returns: The next bucket in the page. 

1957 """ 

1958 name = item.get("name") 

1959 bucket = Bucket(iterator.client, name) 

1960 bucket._set_properties(item) 

1961 return bucket 

1962 

1963 

1964def _item_to_hmac_key_metadata(iterator, item): 

1965 """Convert a JSON key metadata resource to the native object. 

1966 

1967 :type iterator: :class:`~google.api_core.page_iterator.Iterator` 

1968 :param iterator: The iterator that has retrieved the item. 

1969 

1970 :type item: dict 

1971 :param item: An item to be converted to a key metadata instance. 

1972 

1973 :rtype: :class:`~google.cloud.storage.hmac_key.HMACKeyMetadata` 

1974 :returns: The next key metadata instance in the page. 

1975 """ 

1976 metadata = HMACKeyMetadata(iterator.client) 

1977 metadata._properties = item 

1978 return metadata