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

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

360 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 

67def _buckets_page_start(iterator, page, response): 

68 """Grab unreachable buckets after a :class:`~google.cloud.iterator.Page` started.""" 

69 unreachable = response.get("unreachable", []) 

70 if not isinstance(unreachable, list): 

71 raise TypeError( 

72 f"expected unreachable to be list, but obtained {type(unreachable)}" 

73 ) 

74 page.unreachable = unreachable 

75 

76 

77class Client(ClientWithProject): 

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

79 

80 :type project: str or None 

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

82 passed when creating a topic. If not passed, 

83 falls back to the default inferred from the environment. 

84 

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

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

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

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

89 environment. 

90 

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

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

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

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

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

96 ``credentials`` for the current object. 

97 This parameter should be considered private, and could 

98 change in the future. 

99 

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

101 :param client_info: 

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

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

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

105 or partner tool. 

106 

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

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

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

110 

111 :type use_auth_w_custom_endpoint: bool 

112 :param use_auth_w_custom_endpoint: 

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

114 If false, uses AnonymousCredentials and bypasses authentication. 

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

116 

117 :type extra_headers: dict 

118 :param extra_headers: 

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

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

121 

122 :type api_key: string 

123 :param api_key: 

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

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

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

127 """ 

128 

129 SCOPE = ( 

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

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

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

133 ) 

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

135 

136 def __init__( 

137 self, 

138 project=_marker, 

139 credentials=None, 

140 _http=None, 

141 client_info=None, 

142 client_options=None, 

143 use_auth_w_custom_endpoint=True, 

144 extra_headers={}, 

145 *, 

146 api_key=None, 

147 ): 

148 self._base_connection = None 

149 

150 if project is None: 

151 no_project = True 

152 project = "<none>" 

153 else: 

154 no_project = False 

155 

156 if project is _marker: 

157 project = None 

158 

159 # Save the initial value of constructor arguments before they 

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

161 self._initial_client_info = client_info 

162 self._initial_client_options = client_options 

163 self._extra_headers = extra_headers 

164 

165 connection_kw_args = {"client_info": client_info} 

166 

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

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

169 # None. 

170 if api_key: 

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

172 client_options.api_key = api_key 

173 else: 

174 if not client_options: 

175 client_options = {} 

176 client_options["api_key"] = api_key 

177 

178 if client_options: 

179 if isinstance(client_options, dict): 

180 client_options = google.api_core.client_options.from_dict( 

181 client_options 

182 ) 

183 

184 if client_options and client_options.universe_domain: 

185 self._universe_domain = client_options.universe_domain 

186 else: 

187 self._universe_domain = None 

188 

189 storage_emulator_override = _get_storage_emulator_override() 

190 api_endpoint_override = _get_api_endpoint_override() 

191 

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

193 

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

195 # endpoint. 

196 if client_options and client_options.api_endpoint: 

197 api_endpoint = client_options.api_endpoint 

198 

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

200 # endpoint. 

201 elif storage_emulator_override: 

202 api_endpoint = storage_emulator_override 

203 

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

205 # endpoint. 

206 elif api_endpoint_override: 

207 api_endpoint = api_endpoint_override 

208 

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

210 # create the endpoint using that as the default. 

211 # 

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

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

214 # "GOOGLE_API_USE_CLIENT_CERTIFICATE" env variable, a ValueError will 

215 # be raised. 

216 

217 elif self._universe_domain: 

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

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

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

221 if _use_client_cert(): 

222 raise ValueError( 

223 'The "GOOGLE_API_USE_CLIENT_CERTIFICATE" env variable is ' 

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

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

226 "googleapis.com." 

227 ) 

228 api_endpoint = _DEFAULT_SCHEME + _STORAGE_HOST_TEMPLATE.format( 

229 universe_domain=self._universe_domain 

230 ) 

231 

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

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

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

235 else: 

236 api_endpoint = None 

237 

238 connection_kw_args["api_endpoint"] = api_endpoint 

239 

240 self._is_emulator_set = True if storage_emulator_override else False 

241 

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

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

244 # Authentication may be bypassed under certain conditions: 

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

246 # (2) use_auth_w_custom_endpoint is set to False. 

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

248 if self._is_emulator_set or not use_auth_w_custom_endpoint: 

249 if credentials is None: 

250 credentials = AnonymousCredentials() 

251 if project is None: 

252 project = _get_environ_project() 

253 if project is None: 

254 no_project = True 

255 project = "<none>" 

256 

257 super(Client, self).__init__( 

258 project=project, 

259 credentials=credentials, 

260 client_options=client_options, 

261 _http=_http, 

262 ) 

263 

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

265 # universe domain of the client. 

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

267 raise ValueError( 

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

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

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

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

272 client_ud=self.universe_domain, 

273 cred_ud=self._credentials.universe_domain, 

274 ) 

275 ) 

276 

277 if no_project: 

278 self.project = None 

279 

280 # Pass extra_headers to Connection 

281 connection = Connection(self, **connection_kw_args) 

282 connection.extra_headers = extra_headers 

283 self._connection = connection 

284 self._batch_stack = _LocalStack() 

285 

286 @classmethod 

287 def create_anonymous_client(cls): 

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

289 

290 .. note:: 

291 

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

293 listing their contents and downloading their blobs. 

294 

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

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

297 """ 

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

299 client.project = None 

300 return client 

301 

302 @property 

303 def universe_domain(self): 

304 return self._universe_domain or _DEFAULT_UNIVERSE_DOMAIN 

305 

306 @property 

307 def api_endpoint(self): 

308 return self._connection.API_BASE_URL 

309 

310 def update_user_agent(self, user_agent): 

311 """Update the user-agent string for this client. 

312 

313 :type user_agent: str 

314 :param user_agent: The string to add to the user-agent. 

315 """ 

316 existing_user_agent = self._connection._client_info.user_agent 

317 if existing_user_agent is None: 

318 self._connection.user_agent = user_agent 

319 else: 

320 self._connection.user_agent = f"{user_agent} {existing_user_agent}" 

321 

322 @property 

323 def _connection(self): 

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

325 

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

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

328 if one is set. 

329 """ 

330 if self.current_batch is not None: 

331 return self.current_batch 

332 else: 

333 return self._base_connection 

334 

335 @_connection.setter 

336 def _connection(self, value): 

337 """Set connection on the client. 

338 

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

340 self._connection = connection 

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

342 

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

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

345 

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

347 """ 

348 if self._base_connection is not None: 

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

350 self._base_connection = value 

351 

352 def _push_batch(self, batch): 

353 """Push a batch onto our stack. 

354 

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

356 

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

358 :param batch: newly-active batch 

359 """ 

360 self._batch_stack.push(batch) 

361 

362 def _pop_batch(self): 

363 """Pop a batch from our stack. 

364 

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

366 

367 :raises: IndexError if the stack is empty. 

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

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

370 """ 

371 return self._batch_stack.pop() 

372 

373 @property 

374 def current_batch(self): 

375 """Currently-active batch. 

376 

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

378 no batch is active). 

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

380 """ 

381 return self._batch_stack.top 

382 

383 def get_service_account_email( 

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

385 ): 

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

387 

388 :type project: str 

389 :param project: 

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

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

392 :type timeout: float or tuple 

393 :param timeout: 

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

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

396 

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

398 :param retry: 

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

400 

401 :rtype: str 

402 :returns: service account email address 

403 """ 

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

405 if project is None: 

406 project = self.project 

407 

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

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

410 return api_response["email_address"] 

411 

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

413 """Factory constructor for bucket object. 

414 

415 .. note:: 

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

417 a bucket object owned by this client. 

418 

419 :type bucket_name: str 

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

421 

422 :type user_project: str 

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

424 requests made via the bucket. 

425 

426 :type generation: int 

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

428 this bucket. 

429 

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

431 :returns: The bucket object created. 

432 """ 

433 return Bucket( 

434 client=self, 

435 name=bucket_name, 

436 user_project=user_project, 

437 generation=generation, 

438 ) 

439 

440 def batch(self, raise_exception=True): 

441 """Factory constructor for batch object. 

442 

443 .. note:: 

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

445 a batch object owned by this client. 

446 

447 :type raise_exception: bool 

448 :param raise_exception: 

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

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

451 Note that exceptions are unwrapped after all operations are complete 

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

453 

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

455 :returns: The batch object created. 

456 """ 

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

458 

459 def _get_resource( 

460 self, 

461 path, 

462 query_params=None, 

463 headers=None, 

464 timeout=_DEFAULT_TIMEOUT, 

465 retry=DEFAULT_RETRY, 

466 _target_object=None, 

467 ): 

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

469 

470 Args: 

471 path str: 

472 The path of the resource to fetch. 

473 

474 query_params Optional[dict]: 

475 HTTP query parameters to be passed 

476 

477 headers Optional[dict]: 

478 HTTP headers to be passed 

479 

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

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

482 

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

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

485 

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

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

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

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

490 

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

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

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

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

495 if_metageneration_match is set. 

496 

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

498 information on retry types and how to configure them. 

499 

500 _target_object (Union[ \ 

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

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

503 ]): 

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

505 in the context of a batch. 

506 

507 Returns: 

508 dict 

509 The JSON resource fetched 

510 

511 Raises: 

512 google.cloud.exceptions.NotFound 

513 If the bucket is not found. 

514 """ 

515 return self._connection.api_request( 

516 method="GET", 

517 path=path, 

518 query_params=query_params, 

519 headers=headers, 

520 timeout=timeout, 

521 retry=retry, 

522 _target_object=_target_object, 

523 ) 

524 

525 def _list_resource( 

526 self, 

527 path, 

528 item_to_value, 

529 page_token=None, 

530 max_results=None, 

531 extra_params=None, 

532 page_start=page_iterator._do_nothing_page_start, 

533 page_size=None, 

534 timeout=_DEFAULT_TIMEOUT, 

535 retry=DEFAULT_RETRY, 

536 ): 

537 kwargs = { 

538 "method": "GET", 

539 "path": path, 

540 "timeout": timeout, 

541 } 

542 with create_trace_span( 

543 name="Storage.Client._list_resource_returns_iterator", 

544 client=self, 

545 api_request=kwargs, 

546 retry=retry, 

547 ): 

548 api_request = functools.partial( 

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

550 ) 

551 return page_iterator.HTTPIterator( 

552 client=self, 

553 api_request=api_request, 

554 path=path, 

555 item_to_value=item_to_value, 

556 page_token=page_token, 

557 max_results=max_results, 

558 extra_params=extra_params, 

559 page_start=page_start, 

560 page_size=page_size, 

561 ) 

562 

563 def _patch_resource( 

564 self, 

565 path, 

566 data, 

567 query_params=None, 

568 headers=None, 

569 timeout=_DEFAULT_TIMEOUT, 

570 retry=None, 

571 _target_object=None, 

572 ): 

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

574 

575 Args: 

576 path str: 

577 The path of the resource to fetch. 

578 

579 data dict: 

580 The data to be patched. 

581 

582 query_params Optional[dict]: 

583 HTTP query parameters to be passed 

584 

585 headers Optional[dict]: 

586 HTTP headers to be passed 

587 

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

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

590 

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

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

593 

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

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

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

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

598 

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

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

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

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

603 if_metageneration_match is set. 

604 

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

606 information on retry types and how to configure them. 

607 

608 _target_object (Union[ \ 

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

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

611 ]): 

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

613 in the context of a batch. 

614 

615 Returns: 

616 dict 

617 The JSON resource fetched 

618 

619 Raises: 

620 google.cloud.exceptions.NotFound 

621 If the bucket is not found. 

622 """ 

623 return self._connection.api_request( 

624 method="PATCH", 

625 path=path, 

626 data=data, 

627 query_params=query_params, 

628 headers=headers, 

629 timeout=timeout, 

630 retry=retry, 

631 _target_object=_target_object, 

632 ) 

633 

634 def _put_resource( 

635 self, 

636 path, 

637 data, 

638 query_params=None, 

639 headers=None, 

640 timeout=_DEFAULT_TIMEOUT, 

641 retry=None, 

642 _target_object=None, 

643 ): 

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

645 

646 Args: 

647 path str: 

648 The path of the resource to fetch. 

649 

650 data dict: 

651 The data to be patched. 

652 

653 query_params Optional[dict]: 

654 HTTP query parameters to be passed 

655 

656 headers Optional[dict]: 

657 HTTP headers to be passed 

658 

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

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

661 

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

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

664 

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

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

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

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

669 

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

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

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

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

674 if_metageneration_match is set. 

675 

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

677 information on retry types and how to configure them. 

678 

679 _target_object (Union[ \ 

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

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

682 ]): 

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

684 in the context of a batch. 

685 

686 Returns: 

687 dict 

688 The JSON resource fetched 

689 

690 Raises: 

691 google.cloud.exceptions.NotFound 

692 If the bucket is not found. 

693 """ 

694 return self._connection.api_request( 

695 method="PUT", 

696 path=path, 

697 data=data, 

698 query_params=query_params, 

699 headers=headers, 

700 timeout=timeout, 

701 retry=retry, 

702 _target_object=_target_object, 

703 ) 

704 

705 def _post_resource( 

706 self, 

707 path, 

708 data, 

709 query_params=None, 

710 headers=None, 

711 timeout=_DEFAULT_TIMEOUT, 

712 retry=None, 

713 _target_object=None, 

714 ): 

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

716 

717 Args: 

718 path str: 

719 The path of the resource to which to post. 

720 

721 data dict: 

722 The data to be posted. 

723 

724 query_params Optional[dict]: 

725 HTTP query parameters to be passed 

726 

727 headers Optional[dict]: 

728 HTTP headers to be passed 

729 

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

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

732 

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

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

735 

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

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

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

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

740 

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

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

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

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

745 if_metageneration_match is set. 

746 

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

748 information on retry types and how to configure them. 

749 

750 _target_object (Union[ \ 

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

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

753 ]): 

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

755 in the context of a batch. 

756 

757 Returns: 

758 dict 

759 The JSON resource returned from the post. 

760 

761 Raises: 

762 google.cloud.exceptions.NotFound 

763 If the bucket is not found. 

764 """ 

765 

766 return self._connection.api_request( 

767 method="POST", 

768 path=path, 

769 data=data, 

770 query_params=query_params, 

771 headers=headers, 

772 timeout=timeout, 

773 retry=retry, 

774 _target_object=_target_object, 

775 ) 

776 

777 def _delete_resource( 

778 self, 

779 path, 

780 query_params=None, 

781 headers=None, 

782 timeout=_DEFAULT_TIMEOUT, 

783 retry=DEFAULT_RETRY, 

784 _target_object=None, 

785 ): 

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

787 

788 Args: 

789 path str: 

790 The path of the resource to delete. 

791 

792 query_params Optional[dict]: 

793 HTTP query parameters to be passed 

794 

795 headers Optional[dict]: 

796 HTTP headers to be passed 

797 

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

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

800 

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

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

803 

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

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

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

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

808 

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

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

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

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

813 if_metageneration_match is set. 

814 

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

816 information on retry types and how to configure them. 

817 

818 _target_object (Union[ \ 

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

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

821 ]): 

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

823 in the context of a batch. 

824 

825 Returns: 

826 dict 

827 The JSON resource fetched 

828 

829 Raises: 

830 google.cloud.exceptions.NotFound 

831 If the bucket is not found. 

832 """ 

833 return self._connection.api_request( 

834 method="DELETE", 

835 path=path, 

836 query_params=query_params, 

837 headers=headers, 

838 timeout=timeout, 

839 retry=retry, 

840 _target_object=_target_object, 

841 ) 

842 

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

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

845 

846 Args: 

847 bucket_or_name (Union[ \ 

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

849 str, \ 

850 ]): 

851 The bucket resource to pass or name to create. 

852 generation (Optional[int]): 

853 The bucket generation. If generation is specified, 

854 bucket_or_name must be a name (str). 

855 

856 Returns: 

857 google.cloud.storage.bucket.Bucket 

858 The newly created bucket or the given one. 

859 """ 

860 if isinstance(bucket_or_name, Bucket): 

861 if generation: 

862 raise ValueError( 

863 "The generation can only be specified if a " 

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

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

866 "instead." 

867 ) 

868 bucket = bucket_or_name 

869 if bucket.client is None: 

870 bucket._client = self 

871 else: 

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

873 return bucket 

874 

875 def get_bucket( 

876 self, 

877 bucket_or_name, 

878 timeout=_DEFAULT_TIMEOUT, 

879 if_metageneration_match=None, 

880 if_metageneration_not_match=None, 

881 retry=DEFAULT_RETRY, 

882 *, 

883 generation=None, 

884 soft_deleted=None, 

885 ): 

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

887 

888 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). 

889 

890 Args: 

891 bucket_or_name (Union[ \ 

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

893 str, \ 

894 ]): 

895 The bucket resource to pass or name to create. 

896 

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

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

899 

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

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

902 

903 if_metageneration_match (Optional[int]): 

904 Make the operation conditional on whether the 

905 bucket's current metageneration matches the given value. 

906 

907 if_metageneration_not_match (Optional[int]): 

908 Make the operation conditional on whether the bucket's 

909 current metageneration does not match the given value. 

910 

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

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

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

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

915 

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

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

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

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

920 if_metageneration_match is set. 

921 

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

923 information on retry types and how to configure them. 

924 

925 generation (Optional[int]): 

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

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

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

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

930 

931 soft_deleted (Optional[bool]): 

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

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

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

935 ``soft_deleted`` is set to True. 

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

937 

938 Returns: 

939 google.cloud.storage.bucket.Bucket 

940 The bucket matching the name provided. 

941 

942 Raises: 

943 google.cloud.exceptions.NotFound 

944 If the bucket is not found. 

945 """ 

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

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

948 bucket.reload( 

949 client=self, 

950 timeout=timeout, 

951 if_metageneration_match=if_metageneration_match, 

952 if_metageneration_not_match=if_metageneration_not_match, 

953 retry=retry, 

954 soft_deleted=soft_deleted, 

955 ) 

956 return bucket 

957 

958 def lookup_bucket( 

959 self, 

960 bucket_name, 

961 timeout=_DEFAULT_TIMEOUT, 

962 if_metageneration_match=None, 

963 if_metageneration_not_match=None, 

964 retry=DEFAULT_RETRY, 

965 ): 

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

967 

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

969 than catching a NotFound exception. 

970 

971 :type bucket_name: str 

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

973 

974 :type timeout: float or tuple 

975 :param timeout: 

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

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

978 

979 :type if_metageneration_match: long 

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

981 blob's current metageneration matches the given value. 

982 

983 :type if_metageneration_not_match: long 

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

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

986 

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

988 :param retry: 

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

990 

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

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

993 """ 

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

995 try: 

996 return self.get_bucket( 

997 bucket_name, 

998 timeout=timeout, 

999 if_metageneration_match=if_metageneration_match, 

1000 if_metageneration_not_match=if_metageneration_not_match, 

1001 retry=retry, 

1002 ) 

1003 except NotFound: 

1004 return None 

1005 

1006 def create_bucket( 

1007 self, 

1008 bucket_or_name, 

1009 requester_pays=None, 

1010 project=None, 

1011 user_project=None, 

1012 location=None, 

1013 data_locations=None, 

1014 predefined_acl=None, 

1015 predefined_default_object_acl=None, 

1016 enable_object_retention=False, 

1017 timeout=_DEFAULT_TIMEOUT, 

1018 retry=DEFAULT_RETRY, 

1019 ): 

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

1021 

1022 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). 

1023 

1024 Args: 

1025 bucket_or_name (Union[ \ 

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

1027 str, \ 

1028 ]): 

1029 The bucket resource to pass or name to create. 

1030 requester_pays (bool): 

1031 DEPRECATED. Use Bucket().requester_pays instead. 

1032 (Optional) Whether requester pays for API requests for 

1033 this bucket and its blobs. 

1034 project (str): 

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

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

1037 user_project (str): 

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

1039 made via created bucket. 

1040 location (str): 

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

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

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

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

1045 data_locations (list of str): 

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

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

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

1049 predefined_acl (str): 

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

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

1052 predefined_default_object_acl (str): 

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

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

1055 enable_object_retention (bool): 

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

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

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

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

1060 

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

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

1063 

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

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

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

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

1068 

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

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

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

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

1073 if_metageneration_match is set. 

1074 

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

1076 information on retry types and how to configure them. 

1077 

1078 Returns: 

1079 google.cloud.storage.bucket.Bucket 

1080 The newly created bucket. 

1081 

1082 Raises: 

1083 google.cloud.exceptions.Conflict 

1084 If the bucket already exists. 

1085 """ 

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

1087 bucket = self._bucket_arg_to_bucket(bucket_or_name) 

1088 query_params = {} 

1089 

1090 if project is None: 

1091 project = self.project 

1092 

1093 # Use no project if STORAGE_EMULATOR_HOST is set 

1094 if self._is_emulator_set: 

1095 if project is None: 

1096 project = _get_environ_project() 

1097 if project is None: 

1098 project = "<none>" 

1099 

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

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

1102 if project is not None: 

1103 query_params = {"project": project} 

1104 

1105 if requester_pays is not None: 

1106 warnings.warn( 

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

1108 PendingDeprecationWarning, 

1109 stacklevel=1, 

1110 ) 

1111 bucket.requester_pays = requester_pays 

1112 

1113 if predefined_acl is not None: 

1114 predefined_acl = BucketACL.validate_predefined(predefined_acl) 

1115 query_params["predefinedAcl"] = predefined_acl 

1116 

1117 if predefined_default_object_acl is not None: 

1118 predefined_default_object_acl = DefaultObjectACL.validate_predefined( 

1119 predefined_default_object_acl 

1120 ) 

1121 query_params[ 

1122 "predefinedDefaultObjectAcl" 

1123 ] = predefined_default_object_acl 

1124 

1125 if user_project is not None: 

1126 query_params["userProject"] = user_project 

1127 

1128 if enable_object_retention: 

1129 query_params["enableObjectRetention"] = enable_object_retention 

1130 

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

1132 properties["name"] = bucket.name 

1133 

1134 if location is not None: 

1135 properties["location"] = location 

1136 

1137 if data_locations is not None: 

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

1139 

1140 api_response = self._post_resource( 

1141 "/b", 

1142 properties, 

1143 query_params=query_params, 

1144 timeout=timeout, 

1145 retry=retry, 

1146 _target_object=bucket, 

1147 ) 

1148 

1149 bucket._set_properties(api_response) 

1150 return bucket 

1151 

1152 def download_blob_to_file( 

1153 self, 

1154 blob_or_uri, 

1155 file_obj, 

1156 start=None, 

1157 end=None, 

1158 raw_download=False, 

1159 if_etag_match=None, 

1160 if_etag_not_match=None, 

1161 if_generation_match=None, 

1162 if_generation_not_match=None, 

1163 if_metageneration_match=None, 

1164 if_metageneration_not_match=None, 

1165 timeout=_DEFAULT_TIMEOUT, 

1166 checksum="auto", 

1167 retry=DEFAULT_RETRY, 

1168 single_shot_download=False, 

1169 ): 

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

1171 

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

1173 

1174 Args: 

1175 blob_or_uri (Union[ \ 

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

1177 str, \ 

1178 ]): 

1179 The blob resource to pass or URI to download. 

1180 

1181 file_obj (file): 

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

1183 

1184 start (int): 

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

1186 

1187 end (int): 

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

1189 

1190 raw_download (bool): 

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

1192 

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

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

1195 

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

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

1198 

1199 if_generation_match (long): 

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

1201 

1202 if_generation_not_match (long): 

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

1204 

1205 if_metageneration_match (long): 

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

1207 

1208 if_metageneration_not_match (long): 

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

1210 

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

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

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

1214 

1215 checksum (str): 

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

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

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

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

1220 remote service does not know the correct checksum, including 

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

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

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

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

1225 

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

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

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

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

1230 configure backoff and timeout options. 

1231 

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

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

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

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

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

1237 condition such as if_metageneration_match is set. 

1238 

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

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

1241 to configure them. 

1242 

1243 single_shot_download (bool): 

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

1245 """ 

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

1247 if not isinstance(blob_or_uri, Blob): 

1248 blob_or_uri = Blob.from_uri(blob_or_uri) 

1249 

1250 blob_or_uri._prep_and_do_download( 

1251 file_obj, 

1252 client=self, 

1253 start=start, 

1254 end=end, 

1255 raw_download=raw_download, 

1256 if_etag_match=if_etag_match, 

1257 if_etag_not_match=if_etag_not_match, 

1258 if_generation_match=if_generation_match, 

1259 if_generation_not_match=if_generation_not_match, 

1260 if_metageneration_match=if_metageneration_match, 

1261 if_metageneration_not_match=if_metageneration_not_match, 

1262 timeout=timeout, 

1263 checksum=checksum, 

1264 retry=retry, 

1265 single_shot_download=single_shot_download, 

1266 ) 

1267 

1268 def list_blobs( 

1269 self, 

1270 bucket_or_name, 

1271 max_results=None, 

1272 page_token=None, 

1273 prefix=None, 

1274 delimiter=None, 

1275 start_offset=None, 

1276 end_offset=None, 

1277 include_trailing_delimiter=None, 

1278 versions=None, 

1279 projection="noAcl", 

1280 fields=None, 

1281 page_size=None, 

1282 timeout=_DEFAULT_TIMEOUT, 

1283 retry=DEFAULT_RETRY, 

1284 match_glob=None, 

1285 include_folders_as_prefixes=None, 

1286 soft_deleted=None, 

1287 ): 

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

1289 

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

1291 

1292 .. note:: 

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

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

1295 listing objects using a prefix filter. 

1296 

1297 Args: 

1298 bucket_or_name (Union[ \ 

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

1300 str, \ 

1301 ]): 

1302 The bucket resource to pass or name to create. 

1303 

1304 max_results (int): 

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

1306 

1307 page_token (str): 

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

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

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

1311 property of the returned iterator instead of manually passing the 

1312 token. 

1313 

1314 prefix (str): 

1315 (Optional) Prefix used to filter blobs. 

1316 

1317 delimiter (str): 

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

1319 emulate hierarchy. 

1320 

1321 start_offset (str): 

1322 (Optional) Filter results to objects whose names are 

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

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

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

1326 (exclusive). 

1327 

1328 end_offset (str): 

1329 (Optional) Filter results to objects whose names are 

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

1331 also set, the objects listed will have names between 

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

1333 

1334 include_trailing_delimiter (boolean): 

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

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

1337 addition to ``prefixes``. 

1338 

1339 versions (bool): 

1340 (Optional) Whether object versions should be returned 

1341 as separate blobs. 

1342 

1343 projection (str): 

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

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

1346 properties to return. 

1347 

1348 fields (str): 

1349 (Optional) Selector specifying which fields to include 

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

1351 example to get a partial response with just the next 

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

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

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

1355 

1356 page_size (int): 

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

1358 Defaults to a value set by the API. 

1359 

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

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

1362 

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

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

1365 

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

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

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

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

1370 

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

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

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

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

1375 if_metageneration_match is set. 

1376 

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

1378 information on retry types and how to configure them. 

1379 

1380 match_glob (str): 

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

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

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

1384 

1385 include_folders_as_prefixes (bool): 

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

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

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

1389 

1390 soft_deleted (bool): 

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

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

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

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

1395 

1396 Returns: 

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

1398 in this bucket matching the arguments. The RPC call 

1399 returns a response when the iterator is consumed. 

1400 

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

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

1403 """ 

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

1405 bucket = self._bucket_arg_to_bucket(bucket_or_name) 

1406 

1407 extra_params = {"projection": projection} 

1408 

1409 if prefix is not None: 

1410 extra_params["prefix"] = prefix 

1411 

1412 if delimiter is not None: 

1413 extra_params["delimiter"] = delimiter 

1414 

1415 if match_glob is not None: 

1416 extra_params["matchGlob"] = match_glob 

1417 

1418 if start_offset is not None: 

1419 extra_params["startOffset"] = start_offset 

1420 

1421 if end_offset is not None: 

1422 extra_params["endOffset"] = end_offset 

1423 

1424 if include_trailing_delimiter is not None: 

1425 extra_params["includeTrailingDelimiter"] = include_trailing_delimiter 

1426 

1427 if versions is not None: 

1428 extra_params["versions"] = versions 

1429 

1430 if fields is not None: 

1431 extra_params["fields"] = fields 

1432 

1433 if include_folders_as_prefixes is not None: 

1434 extra_params["includeFoldersAsPrefixes"] = include_folders_as_prefixes 

1435 

1436 if soft_deleted is not None: 

1437 extra_params["softDeleted"] = soft_deleted 

1438 

1439 if bucket.user_project is not None: 

1440 extra_params["userProject"] = bucket.user_project 

1441 

1442 path = bucket.path + "/o" 

1443 iterator = self._list_resource( 

1444 path, 

1445 _item_to_blob, 

1446 page_token=page_token, 

1447 max_results=max_results, 

1448 extra_params=extra_params, 

1449 page_start=_blobs_page_start, 

1450 page_size=page_size, 

1451 timeout=timeout, 

1452 retry=retry, 

1453 ) 

1454 iterator.bucket = bucket 

1455 iterator.prefixes = set() 

1456 return iterator 

1457 

1458 def list_buckets( 

1459 self, 

1460 max_results=None, 

1461 page_token=None, 

1462 prefix=None, 

1463 projection="noAcl", 

1464 fields=None, 

1465 project=None, 

1466 page_size=None, 

1467 timeout=_DEFAULT_TIMEOUT, 

1468 retry=DEFAULT_RETRY, 

1469 *, 

1470 soft_deleted=None, 

1471 return_partial_success=None, 

1472 ): 

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

1474 

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

1476 bucket. 

1477 

1478 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). 

1479 

1480 :type max_results: int 

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

1482 

1483 :type page_token: str 

1484 :param page_token: 

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

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

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

1488 property of the returned iterator instead of manually passing the 

1489 token. 

1490 

1491 :type prefix: str 

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

1493 with this prefix. 

1494 

1495 :type projection: str 

1496 :param projection: 

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

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

1499 

1500 :type fields: str 

1501 :param fields: 

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

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

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

1505 bucket returned: 'items/id,nextPageToken' 

1506 

1507 :type project: str 

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

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

1510 

1511 :type page_size: int 

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

1513 Defaults to a value set by the API. 

1514 

1515 :type timeout: float or tuple 

1516 :param timeout: 

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

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

1519 

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

1521 :param retry: 

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

1523 

1524 :type soft_deleted: bool 

1525 :param soft_deleted: 

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

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

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

1529 

1530 :type return_partial_success: bool 

1531 :param return_partial_success: 

1532 (Optional) If True, the response will also contain a list of 

1533 unreachable buckets if the buckets are unavailable. The 

1534 unreachable buckets will be available on the ``unreachable`` 

1535 attribute of the returned iterator. 

1536 

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

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

1539 project is also ``None``. 

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

1541 belonging to this project. 

1542 """ 

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

1544 extra_params = {} 

1545 

1546 if project is None: 

1547 project = self.project 

1548 

1549 # Use no project if STORAGE_EMULATOR_HOST is set 

1550 if self._is_emulator_set: 

1551 if project is None: 

1552 project = _get_environ_project() 

1553 if project is None: 

1554 project = "<none>" 

1555 

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

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

1558 if project is not None: 

1559 extra_params = {"project": project} 

1560 

1561 if prefix is not None: 

1562 extra_params["prefix"] = prefix 

1563 

1564 extra_params["projection"] = projection 

1565 

1566 if fields is not None: 

1567 extra_params["fields"] = fields 

1568 

1569 if soft_deleted is not None: 

1570 extra_params["softDeleted"] = soft_deleted 

1571 

1572 if return_partial_success is not None: 

1573 extra_params["returnPartialSuccess"] = return_partial_success 

1574 

1575 iterator = self._list_resource( 

1576 "/b", 

1577 _item_to_bucket, 

1578 page_token=page_token, 

1579 max_results=max_results, 

1580 extra_params=extra_params, 

1581 page_size=page_size, 

1582 timeout=timeout, 

1583 retry=retry, 

1584 page_start=_buckets_page_start, 

1585 ) 

1586 return iterator 

1587 

1588 def restore_bucket( 

1589 self, 

1590 bucket_name, 

1591 generation, 

1592 projection="noAcl", 

1593 if_metageneration_match=None, 

1594 if_metageneration_not_match=None, 

1595 timeout=_DEFAULT_TIMEOUT, 

1596 retry=DEFAULT_RETRY, 

1597 ): 

1598 """Restores a soft-deleted bucket. 

1599 

1600 :type bucket_name: str 

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

1602 

1603 :type generation: int 

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

1605 

1606 :type projection: str 

1607 :param projection: 

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

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

1610 

1611 if_metageneration_match (Optional[int]): 

1612 Make the operation conditional on whether the 

1613 blob's current metageneration matches the given value. 

1614 

1615 if_metageneration_not_match (Optional[int]): 

1616 Make the operation conditional on whether the blob's 

1617 current metageneration does not match the given value. 

1618 

1619 :type timeout: float or tuple 

1620 :param timeout: 

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

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

1623 

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

1625 :param retry: 

1626 (Optional) How to retry the RPC. 

1627 

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

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

1630 

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

1632 :returns: The restored Bucket. 

1633 """ 

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

1635 

1636 _add_generation_match_parameters( 

1637 query_params, 

1638 if_metageneration_match=if_metageneration_match, 

1639 if_metageneration_not_match=if_metageneration_not_match, 

1640 ) 

1641 

1642 bucket = self.bucket(bucket_name) 

1643 api_response = self._post_resource( 

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

1645 None, 

1646 query_params=query_params, 

1647 timeout=timeout, 

1648 retry=retry, 

1649 ) 

1650 bucket._set_properties(api_response) 

1651 return bucket 

1652 

1653 def create_hmac_key( 

1654 self, 

1655 service_account_email, 

1656 project_id=None, 

1657 user_project=None, 

1658 timeout=_DEFAULT_TIMEOUT, 

1659 retry=None, 

1660 ): 

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

1662 

1663 :type service_account_email: str 

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

1665 

1666 :type project_id: str 

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

1668 Defaults to the client's project. 

1669 

1670 :type user_project: str 

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

1672 

1673 :type timeout: float or tuple 

1674 :param timeout: 

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

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

1677 

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

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

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

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

1682 

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

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

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

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

1687 if_metageneration_match is set. 

1688 

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

1690 information on retry types and how to configure them. 

1691 

1692 :rtype: 

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

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

1695 """ 

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

1697 if project_id is None: 

1698 project_id = self.project 

1699 

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

1701 qs_params = {"serviceAccountEmail": service_account_email} 

1702 

1703 if user_project is not None: 

1704 qs_params["userProject"] = user_project 

1705 

1706 api_response = self._post_resource( 

1707 path, 

1708 None, 

1709 query_params=qs_params, 

1710 timeout=timeout, 

1711 retry=retry, 

1712 ) 

1713 metadata = HMACKeyMetadata(self) 

1714 metadata._properties = api_response["metadata"] 

1715 secret = api_response["secret"] 

1716 return metadata, secret 

1717 

1718 def list_hmac_keys( 

1719 self, 

1720 max_results=None, 

1721 service_account_email=None, 

1722 show_deleted_keys=None, 

1723 project_id=None, 

1724 user_project=None, 

1725 timeout=_DEFAULT_TIMEOUT, 

1726 retry=DEFAULT_RETRY, 

1727 ): 

1728 """List HMAC keys for a project. 

1729 

1730 :type max_results: int 

1731 :param max_results: 

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

1733 

1734 :type service_account_email: str 

1735 :param service_account_email: 

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

1737 

1738 :type show_deleted_keys: bool 

1739 :param show_deleted_keys: 

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

1741 exclude them. 

1742 

1743 :type project_id: str 

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

1745 Defaults to the client's project. 

1746 

1747 :type user_project: str 

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

1749 

1750 :type timeout: float or tuple 

1751 :param timeout: 

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

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

1754 

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

1756 :param retry: 

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

1758 

1759 :rtype: 

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

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

1762 """ 

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

1764 if project_id is None: 

1765 project_id = self.project 

1766 

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

1768 extra_params = {} 

1769 

1770 if service_account_email is not None: 

1771 extra_params["serviceAccountEmail"] = service_account_email 

1772 

1773 if show_deleted_keys is not None: 

1774 extra_params["showDeletedKeys"] = show_deleted_keys 

1775 

1776 if user_project is not None: 

1777 extra_params["userProject"] = user_project 

1778 

1779 return self._list_resource( 

1780 path, 

1781 _item_to_hmac_key_metadata, 

1782 max_results=max_results, 

1783 extra_params=extra_params, 

1784 timeout=timeout, 

1785 retry=retry, 

1786 ) 

1787 

1788 def get_hmac_key_metadata( 

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

1790 ): 

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

1792 

1793 :type access_id: str 

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

1795 

1796 :type project_id: str 

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

1798 Defaults to client's project. 

1799 

1800 :type timeout: float or tuple 

1801 :param timeout: 

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

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

1804 

1805 :type user_project: str 

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

1807 """ 

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

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

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

1811 return metadata 

1812 

1813 def generate_signed_post_policy_v4( 

1814 self, 

1815 bucket_name, 

1816 blob_name, 

1817 expiration, 

1818 conditions=None, 

1819 fields=None, 

1820 credentials=None, 

1821 virtual_hosted_style=False, 

1822 bucket_bound_hostname=None, 

1823 scheme="http", 

1824 service_account_email=None, 

1825 access_token=None, 

1826 ): 

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

1828 

1829 .. note:: 

1830 

1831 Assumes ``credentials`` implements the 

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

1833 ``credentials`` has a ``service_account_email`` property which 

1834 identifies the credentials. 

1835 

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

1837 

1838 :type bucket_name: str 

1839 :param bucket_name: Bucket name. 

1840 

1841 :type blob_name: str 

1842 :param blob_name: Object name. 

1843 

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

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

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

1847 assumed to be ``UTC``. 

1848 

1849 :type conditions: list 

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

1851 used to restrict what is allowed in the request. 

1852 

1853 :type fields: dict 

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

1855 

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

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

1858 key to sign text. 

1859 

1860 :type virtual_hosted_style: bool 

1861 :param virtual_hosted_style: 

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

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

1864 Incompatible with bucket_bound_hostname. 

1865 

1866 :type bucket_bound_hostname: str 

1867 :param bucket_bound_hostname: 

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

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

1870 Incompatible with virtual_hosted_style. 

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

1872 

1873 :type scheme: str 

1874 :param scheme: 

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

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

1877 Defaults to ``"http"``. 

1878 

1879 :type service_account_email: str 

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

1881 

1882 :type access_token: str 

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

1884 

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

1886 

1887 :rtype: dict 

1888 :returns: Signed POST policy. 

1889 """ 

1890 if virtual_hosted_style and bucket_bound_hostname: 

1891 raise ValueError( 

1892 "Only one of virtual_hosted_style and bucket_bound_hostname " 

1893 "can be specified." 

1894 ) 

1895 

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

1897 client_email = service_account_email 

1898 if not access_token or not service_account_email: 

1899 ensure_signed_credentials(credentials) 

1900 client_email = credentials.signer_email 

1901 

1902 # prepare policy conditions and fields 

1903 timestamp, datestamp = get_v4_now_dtstamps() 

1904 

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

1906 email=client_email, datestamp=datestamp 

1907 ) 

1908 required_conditions = [ 

1909 {"bucket": bucket_name}, 

1910 {"key": blob_name}, 

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

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

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

1914 ] 

1915 

1916 conditions = conditions or [] 

1917 policy_fields = {} 

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

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

1920 policy_fields[key] = value 

1921 conditions.append({key: value}) 

1922 

1923 conditions += required_conditions 

1924 

1925 # calculate policy expiration time 

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

1927 if expiration is None: 

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

1929 

1930 policy_expires = now + datetime.timedelta( 

1931 seconds=get_expiration_seconds_v4(expiration) 

1932 ) 

1933 

1934 # encode policy for signing 

1935 policy = json.dumps( 

1936 collections.OrderedDict( 

1937 sorted( 

1938 { 

1939 "conditions": conditions, 

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

1941 }.items() 

1942 ) 

1943 ), 

1944 separators=(",", ":"), 

1945 ) 

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

1947 

1948 # sign the policy and get its cryptographic signature 

1949 if access_token and service_account_email: 

1950 signature = _sign_message(str_to_sign, access_token, service_account_email) 

1951 signature_bytes = base64.b64decode(signature) 

1952 else: 

1953 signature_bytes = credentials.sign_bytes(str_to_sign) 

1954 

1955 # get hexadecimal representation of the signature 

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

1957 

1958 policy_fields.update( 

1959 { 

1960 "key": blob_name, 

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

1962 "x-goog-credential": x_goog_credential, 

1963 "x-goog-date": timestamp, 

1964 "x-goog-signature": signature, 

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

1966 } 

1967 ) 

1968 # designate URL 

1969 if virtual_hosted_style: 

1970 url = _virtual_hosted_style_base_url( 

1971 self.api_endpoint, bucket_name, trailing_slash=True 

1972 ) 

1973 elif bucket_bound_hostname: 

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

1975 else: 

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

1977 

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

1979 

1980 

1981def _item_to_bucket(iterator, item): 

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

1983 

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

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

1986 

1987 :type item: dict 

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

1989 

1990 :rtype: :class:`.Bucket` 

1991 :returns: The next bucket in the page. 

1992 """ 

1993 name = item.get("name") 

1994 bucket = Bucket(iterator.client, name) 

1995 bucket._set_properties(item) 

1996 return bucket 

1997 

1998 

1999def _item_to_hmac_key_metadata(iterator, item): 

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

2001 

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

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

2004 

2005 :type item: dict 

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

2007 

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

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

2010 """ 

2011 metadata = HMACKeyMetadata(iterator.client) 

2012 metadata._properties = item 

2013 return metadata