From 8d4fdf32719cd27eb2d1979eb650ffc7fb107e14 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Wed, 25 Mar 2026 20:32:43 +0000 Subject: [PATCH 1/2] chore: update files in generator-input --- .../generator-input/.repo-metadata.json | 2 +- .librarian/generator-input/librarian.py | 5 + .librarian/generator-input/noxfile.py | 92 +++++++++++++++---- .librarian/generator-input/setup.py | 38 +++++++- 4 files changed, 118 insertions(+), 19 deletions(-) diff --git a/.librarian/generator-input/.repo-metadata.json b/.librarian/generator-input/.repo-metadata.json index bd870f959..59ebe7f61 100644 --- a/.librarian/generator-input/.repo-metadata.json +++ b/.librarian/generator-input/.repo-metadata.json @@ -12,7 +12,7 @@ "api_id": "storage.googleapis.com", "requires_billing": true, "default_version": "v2", - "codeowner_team": "@googleapis/yoshi-python @googleapis/gcs-sdk-team @googleapis/gcs-fs", + "codeowner_team": "@googleapis/cloud-sdk-python-team @googleapis/gcs-team @googleapis/gcs-fs", "api_shortname": "storage", "api_description": "is a durable and highly available object storage service. Google Cloud Storage is almost infinitely scalable and guarantees consistency: when a write succeeds, the latest copy of the object will be returned to any GET, globally." } diff --git a/.librarian/generator-input/librarian.py b/.librarian/generator-input/librarian.py index ad0baa2a3..853dc8a6f 100644 --- a/.librarian/generator-input/librarian.py +++ b/.librarian/generator-input/librarian.py @@ -45,6 +45,11 @@ "testing/constraints-3.7.txt", "testing/constraints-3.9.txt", "tests/unit/__init__.py", + # Temporarily exclude google/cloud/_storage_v2/services/storage/client.py + # due to customization. + # This exclusion will be removed in the google-cloud-python migration PR + # When librarian.py is dropped. + "google/cloud/storage_v2/services/storage/client.py", ], ) diff --git a/.librarian/generator-input/noxfile.py b/.librarian/generator-input/noxfile.py index c9ada0739..a00b72040 100644 --- a/.librarian/generator-input/noxfile.py +++ b/.librarian/generator-input/noxfile.py @@ -17,7 +17,6 @@ from __future__ import absolute_import import os import pathlib -import re import shutil import nox @@ -28,7 +27,13 @@ DEFAULT_PYTHON_VERSION = "3.14" SYSTEM_TEST_PYTHON_VERSIONS = ["3.10", "3.14"] -UNIT_TEST_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] +UNIT_TEST_PYTHON_VERSIONS = [ + "3.10", + "3.11", + "3.12", + "3.13", + "3.14", +] CONFORMANCE_TEST_PYTHON_VERSIONS = ["3.12"] CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -39,6 +44,7 @@ nox.options.sessions = [ "blacken", "conftest_retry", + "conftest_retry_bidi", "docfx", "docs", "lint", @@ -61,9 +67,7 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - # Pin flake8 to 6.0.0 - # See https://github.com/googleapis/python-storage/issues/1102 - session.install("flake8==6.0.0", BLACK_VERSION) + session.install("flake8", BLACK_VERSION) session.run( "black", "--check", @@ -116,6 +120,8 @@ def default(session, install_extras=True): session.install("-e", ".", "-c", constraints_path) + session.run("python", "-m", "pip", "freeze") + # This dependency is included in setup.py for backwards compatibility only # and the client library is expected to pass all tests without it. See # setup.py and README for details. @@ -180,7 +186,14 @@ def system(session): # 2021-05-06: defer installing 'google-cloud-*' to after this package, # in order to work around Python 2.7 googolapis-common-protos # issue. - session.install("mock", "pytest", "pytest-rerunfailures", "-c", constraints_path) + session.install( + "mock", + "pytest", + "pytest-rerunfailures", + "pytest-asyncio", + "-c", + constraints_path, + ) session.install("-e", ".", "-c", constraints_path) session.install( "google-cloud-testutils", @@ -207,30 +220,75 @@ def system(session): @nox.session(python=CONFORMANCE_TEST_PYTHON_VERSIONS) def conftest_retry(session): """Run the retry conformance test suite.""" - conformance_test_folder_path = os.path.join("tests", "conformance") - conformance_test_folder_exists = os.path.exists(conformance_test_folder_path) + json_conformance_tests = "tests/conformance/test_conformance.py" # Environment check: only run tests if found. - if not conformance_test_folder_exists: + if not os.path.exists(json_conformance_tests): session.skip("Conformance tests were not found") + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + # Install all test dependencies and pytest plugin to run tests in parallel. # Then install this package in-place. - session.install("pytest", "pytest-xdist") - session.install("-e", ".") + session.install( + "pytest", + "pytest-xdist", + "-c", + constraints_path, + ) + session.install("-e", ".", "-c", constraints_path) # Run #CPU processes in parallel if no test session arguments are passed in. if session.posargs: test_cmd = [ - "py.test", - "--quiet", - conformance_test_folder_path, + "pytest", + "-vv", + "-s", + json_conformance_tests, *session.posargs, ] else: - test_cmd = ["py.test", "-n", "auto", "--quiet", conformance_test_folder_path] + test_cmd = ["pytest", "-vv", "-s", "-n", "auto", json_conformance_tests] + + # Run pytest against the conformance tests. + session.run(*test_cmd, env={"DOCKER_API_VERSION": "1.39"}) + - # Run py.test against the conformance tests. - session.run(*test_cmd) +@nox.session(python=CONFORMANCE_TEST_PYTHON_VERSIONS) +def conftest_retry_bidi(session): + """Run the retry conformance test suite.""" + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + + # Install all test dependencies and pytest plugin to run tests in parallel. + # Then install this package in-place. + session.install( + "pytest", + "pytest-xdist", + "pytest-asyncio", + "grpcio", + "grpcio-status", + "grpc-google-iam-v1", + "-c", + constraints_path, + ) + session.install("-e", ".", "-c", constraints_path) + + bidi_tests = [ + "tests/conformance/test_bidi_reads.py", + "tests/conformance/test_bidi_writes.py", + ] + for test_file in bidi_tests: + session.run( + "pytest", + "-vv", + "-s", + test_file, + env={"DOCKER_API_VERSION": "1.39"}, + ) @nox.session(python=DEFAULT_PYTHON_VERSION) diff --git a/.librarian/generator-input/setup.py b/.librarian/generator-input/setup.py index 294e63892..69fc2899e 100644 --- a/.librarian/generator-input/setup.py +++ b/.librarian/generator-input/setup.py @@ -43,10 +43,46 @@ "google-crc32c >= 1.1.3, < 2.0.0", ] extras = { + # TODO: Make these extra dependencies as mandatory once gRPC out of + # experimental in this SDK. More info in b/465352227 + "grpc": [ + "google-api-core[grpc] >= 2.27.0, < 3.0.0", + "grpcio >= 1.33.2, < 2.0.0; python_version < '3.14'", + "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "grpcio-status >= 1.76.0, < 2.0.0", + "proto-plus >= 1.22.3, <2.0.0; python_version < '3.13'", + "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", + "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", + "grpc-google-iam-v1 >= 0.14.0, <1.0.0", + ], "protobuf": ["protobuf >= 3.20.2, < 7.0.0"], "tracing": [ "opentelemetry-api >= 1.1.0, < 2.0.0", ], + "testing": [ + "google-cloud-testutils", + "numpy", + "psutil", + "py-cpuinfo", + "pytest-benchmark", + "PyYAML", + "mock", + "pytest", + "pytest-cov", + "pytest-asyncio", + "pytest-rerunfailures", + "pytest-xdist", + "google-cloud-testutils", + "google-cloud-iam", + "google-cloud-pubsub", + "google-cloud-kms", + "brotli", + "coverage", + "pyopenssl", + "opentelemetry-sdk", + "flake8", + "black", + ], } @@ -99,7 +135,7 @@ packages=packages, install_requires=dependencies, extras_require=extras, - python_requires=">=3.7", + python_requires=">=3.10", include_package_data=True, zip_safe=False, ) From 0fd3e3e896f0d6ee45cf39d74c50ed413aa3641a Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Wed, 25 Mar 2026 20:52:08 +0000 Subject: [PATCH 2/2] feat: generate libraries --- .librarian/state.yaml | 2 +- .../services/storage/async_client.py | 5 +- .../_storage_v2/services/storage/client.py | 4028 ----------------- .../services/storage/transports/grpc.py | 5 +- .../storage/transports/grpc_asyncio.py | 5 +- google/cloud/_storage_v2/types/storage.py | 29 +- noxfile.py | 2 - testing/constraints-3.14.txt | 2 +- tests/unit/gapic/storage_v2/test_storage.py | 254 +- 9 files changed, 61 insertions(+), 4271 deletions(-) delete mode 100644 google/cloud/_storage_v2/services/storage/client.py diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 8c3daafaa..cf8d9f0f9 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-cloud-storage version: 3.10.1 - last_generated_commit: 5400ccce473c439885bd6bf2924fd242271bfcab + last_generated_commit: 1e1ca41d507f31b9ae307efbe002af864358214b apis: - path: google/storage/v2 service_config: storage_v2.yaml diff --git a/google/cloud/_storage_v2/services/storage/async_client.py b/google/cloud/_storage_v2/services/storage/async_client.py index c71ee0472..cd376a088 100644 --- a/google/cloud/_storage_v2/services/storage/async_client.py +++ b/google/cloud/_storage_v2/services/storage/async_client.py @@ -2472,8 +2472,9 @@ def bidi_read_object( across several messages. If an error occurs with any request, the stream closes with a relevant error code. Since you can have multiple outstanding requests, the error response includes a - ``BidiReadObjectRangesError`` field detailing the specific error - for each pending ``read_id``. + ``BidiReadObjectError`` proto in its ``details`` field, + reporting the specific error, if any, for each pending + ``read_id``. **IAM Permissions**: diff --git a/google/cloud/_storage_v2/services/storage/client.py b/google/cloud/_storage_v2/services/storage/client.py deleted file mode 100644 index cdccf3fab..000000000 --- a/google/cloud/_storage_v2/services/storage/client.py +++ /dev/null @@ -1,4028 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Iterable, - Iterator, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.cloud._storage_v2 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - -from google.cloud._storage_v2.services.storage import pagers -from google.cloud._storage_v2.types import storage -from google.iam.v1 import iam_policy_pb2 # type: ignore -from google.iam.v1 import policy_pb2 # type: ignore -from google.longrunning import operations_pb2 # type: ignore -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from .transports.base import StorageTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import StorageGrpcTransport -from .transports.grpc_asyncio import StorageGrpcAsyncIOTransport - - -class StorageClientMeta(type): - """Metaclass for the Storage client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = OrderedDict() # type: Dict[str, Type[StorageTransport]] - _transport_registry["grpc"] = StorageGrpcTransport - _transport_registry["grpc_asyncio"] = StorageGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[StorageTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class StorageClient(metaclass=StorageClientMeta): - """API Overview and Naming Syntax - ------------------------------ - - The Cloud Storage gRPC API allows applications to read and write - data through the abstractions of buckets and objects. For a - description of these abstractions please see `Cloud Storage - documentation `__. - - Resources are named as follows: - - - Projects are referred to as they are defined by the Resource - Manager API, using strings like ``projects/123456`` or - ``projects/my-string-id``. - - - Buckets are named using string names of the form: - ``projects/{project}/buckets/{bucket}``. For globally unique - buckets, ``_`` might be substituted for the project. - - - Objects are uniquely identified by their name along with the name - of the bucket they belong to, as separate strings in this API. For - example: - - :: - - ``` - ReadObjectRequest { - bucket: 'projects/_/buckets/my-bucket' - object: 'my-object' - } - ``` - - Note that object names can contain ``/`` characters, which are - treated as any other character (no special directory semantics). - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "storage.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "storage.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @staticmethod - def _use_client_cert_effective(): - """Returns whether client certificate should be used for mTLS if the - google-auth version supports should_use_client_cert automatic mTLS enablement. - - Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. - - Returns: - bool: whether client certificate should be used for mTLS - Raises: - ValueError: (If using a version of google-auth without should_use_client_cert and - GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) - """ - # check if google-auth version supports should_use_client_cert for automatic mTLS enablement - if hasattr(mtls, "should_use_client_cert"): - return mtls.should_use_client_cert() - else: - # if unsupported, fallback to reading from env var - use_client_cert_str = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - if use_client_cert_str not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" - " either `true` or `false`" - ) - return use_client_cert_str == "true" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - StorageClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info(info) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - StorageClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file(filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> StorageTransport: - """Returns the transport used by the client instance. - - Returns: - StorageTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def bucket_path( - project: str, - bucket: str, - ) -> str: - """Returns a fully-qualified bucket string.""" - return "projects/{project}/buckets/{bucket}".format( - project=project, - bucket=bucket, - ) - - @staticmethod - def parse_bucket_path(path: str) -> Dict[str, str]: - """Parses a bucket path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/buckets/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def crypto_key_path( - project: str, - location: str, - key_ring: str, - crypto_key: str, - ) -> str: - """Returns a fully-qualified crypto_key string.""" - return "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}".format( - project=project, - location=location, - key_ring=key_ring, - crypto_key=crypto_key, - ) - - @staticmethod - def parse_crypto_key_path(path: str) -> Dict[str, str]: - """Parses a crypto_key path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/keyRings/(?P.+?)/cryptoKeys/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = StorageClient._use_client_cert_effective() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert: - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = StorageClient._use_client_cert_effective() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert, use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = StorageClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = StorageClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = StorageClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], universe_domain_env: Optional[str] - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = StorageClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[str, StorageTransport, Callable[..., StorageTransport]] - ] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the storage client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,StorageTransport,Callable[..., StorageTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the StorageTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr(self._client_options, "universe_domain", None) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = StorageClient._read_environment_variables() - self._client_cert_source = StorageClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = StorageClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER - # Setup logging. - client_logging.initialize_logging() - - api_key_value = getattr(self._client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, StorageTransport) - if transport_provided: - # transport is a StorageTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(StorageTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = self._api_endpoint or StorageClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[StorageTransport], Callable[..., StorageTransport] - ] = ( - StorageClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., StorageTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - if "async" not in str(self._transport): - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.storage_v2.StorageClient`.", - extra={ - "serviceName": "google.storage.v2.Storage", - "universeDomain": getattr( - self._transport._credentials, "universe_domain", "" - ), - "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", - "credentialsInfo": getattr( - self.transport._credentials, "get_cred_info", lambda: None - )(), - } - if hasattr(self._transport, "_credentials") - else { - "serviceName": "google.storage.v2.Storage", - "credentialsType": None, - }, - ) - - def delete_bucket( - self, - request: Optional[Union[storage.DeleteBucketRequest, dict]] = None, - *, - name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Permanently deletes an empty bucket. The request fails if there - are any live or noncurrent objects in the bucket, but the - request succeeds if the bucket only contains soft-deleted - objects or incomplete uploads, such as ongoing XML API multipart - uploads. Does not permanently delete soft-deleted objects. - - When this API is used to delete a bucket containing an object - that has a soft delete policy enabled, the object becomes soft - deleted, and the ``softDeleteTime`` and ``hardDeleteTime`` - properties are set on the object. - - Objects and multipart uploads that were in the bucket at the - time of deletion are also retained for the specified retention - duration. When a soft-deleted bucket reaches the end of its - retention duration, it is permanently deleted. The - ``hardDeleteTime`` of the bucket always equals or exceeds the - expiration time of the last soft-deleted object in the bucket. - - **IAM Permissions**: - - Requires ``storage.buckets.delete`` IAM permission on the - bucket. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_delete_bucket(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.DeleteBucketRequest( - name="name_value", - ) - - # Make the request - client.delete_bucket(request=request) - - Args: - request (Union[google.cloud._storage_v2.types.DeleteBucketRequest, dict]): - The request object. Request message for - [DeleteBucket][google.storage.v2.Storage.DeleteBucket]. - name (str): - Required. Name of a bucket to delete. - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.DeleteBucketRequest): - request = storage.DeleteBucketRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.delete_bucket] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.name) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def get_bucket( - self, - request: Optional[Union[storage.GetBucketRequest, dict]] = None, - *, - name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Bucket: - r"""Returns metadata for the specified bucket. - - **IAM Permissions**: - - Requires ``storage.buckets.get`` IAM permission on the bucket. - Additionally, to return specific bucket metadata, the - authenticated user must have the following permissions: - - - To return the IAM policies: ``storage.buckets.getIamPolicy`` - - To return the bucket IP filtering rules: - ``storage.buckets.getIpFilter`` - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_get_bucket(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.GetBucketRequest( - name="name_value", - ) - - # Make the request - response = client.get_bucket(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.GetBucketRequest, dict]): - The request object. Request message for - [GetBucket][google.storage.v2.Storage.GetBucket]. - name (str): - Required. Name of a bucket. - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Bucket: - A bucket. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.GetBucketRequest): - request = storage.GetBucketRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.get_bucket] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.name) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def create_bucket( - self, - request: Optional[Union[storage.CreateBucketRequest, dict]] = None, - *, - parent: Optional[str] = None, - bucket: Optional[storage.Bucket] = None, - bucket_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Bucket: - r"""Creates a new bucket. - - **IAM Permissions**: - - Requires ``storage.buckets.create`` IAM permission on the - bucket. Additionally, to enable specific bucket features, the - authenticated user must have the following permissions: - - - To enable object retention using the ``enableObjectRetention`` - query parameter: ``storage.buckets.enableObjectRetention`` - - To set the bucket IP filtering rules: - ``storage.buckets.setIpFilter`` - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_create_bucket(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.CreateBucketRequest( - parent="parent_value", - bucket_id="bucket_id_value", - ) - - # Make the request - response = client.create_bucket(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.CreateBucketRequest, dict]): - The request object. Request message for - [CreateBucket][google.storage.v2.Storage.CreateBucket]. - parent (str): - Required. The project to which this bucket belongs. This - field must either be empty or ``projects/_``. The - project ID that owns this bucket should be specified in - the ``bucket.project`` field. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - bucket (google.cloud._storage_v2.types.Bucket): - Optional. Properties of the new bucket being inserted. - The name of the bucket is specified in the ``bucket_id`` - field. Populating ``bucket.name`` field results in an - error. The project of the bucket must be specified in - the ``bucket.project`` field. This field must be in - ``projects/{projectIdentifier}`` format, - {projectIdentifier} can be the project ID or project - number. The ``parent`` field must be either empty or - ``projects/_``. - - This corresponds to the ``bucket`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - bucket_id (str): - Required. The ID to use for this bucket, which becomes - the final component of the bucket's resource name. For - example, the value ``foo`` might result in a bucket with - the name ``projects/123456/buckets/foo``. - - This corresponds to the ``bucket_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Bucket: - A bucket. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [parent, bucket, bucket_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.CreateBucketRequest): - request = storage.CreateBucketRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if bucket is not None: - request.bucket = bucket - if bucket_id is not None: - request.bucket_id = bucket_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.create_bucket] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.parent) - if regex_match and regex_match.group("project"): - header_params["project"] = regex_match.group("project") - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.bucket.project) - if regex_match and regex_match.group("project"): - header_params["project"] = regex_match.group("project") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_buckets( - self, - request: Optional[Union[storage.ListBucketsRequest, dict]] = None, - *, - parent: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListBucketsPager: - r"""Retrieves a list of buckets for a given project, ordered - lexicographically by name. - - **IAM Permissions**: - - Requires ``storage.buckets.list`` IAM permission on the bucket. - Additionally, to enable specific bucket features, the - authenticated user must have the following permissions: - - - To list the IAM policies: ``storage.buckets.getIamPolicy`` - - To list the bucket IP filtering rules: - ``storage.buckets.getIpFilter`` - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_list_buckets(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.ListBucketsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_buckets(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.ListBucketsRequest, dict]): - The request object. Request message for - [ListBuckets][google.storage.v2.Storage.ListBuckets]. - parent (str): - Required. The project whose buckets - we are listing. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.services.storage.pagers.ListBucketsPager: - Response message for - [ListBuckets][google.storage.v2.Storage.ListBuckets]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [parent] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.ListBucketsRequest): - request = storage.ListBucketsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_buckets] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.parent) - if regex_match and regex_match.group("project"): - header_params["project"] = regex_match.group("project") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListBucketsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def lock_bucket_retention_policy( - self, - request: Optional[Union[storage.LockBucketRetentionPolicyRequest, dict]] = None, - *, - bucket: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Bucket: - r"""Permanently locks the retention policy that is currently applied - to the specified bucket. - - Caution: Locking a bucket is an irreversible action. Once you - lock a bucket: - - - You cannot remove the retention policy from the bucket. - - You cannot decrease the retention period for the policy. - - Once locked, you must delete the entire bucket in order to - remove the bucket's retention policy. However, before you can - delete the bucket, you must delete all the objects in the - bucket, which is only possible if all the objects have reached - the retention period set by the retention policy. - - **IAM Permissions**: - - Requires ``storage.buckets.update`` IAM permission on the - bucket. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_lock_bucket_retention_policy(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.LockBucketRetentionPolicyRequest( - bucket="bucket_value", - if_metageneration_match=2413, - ) - - # Make the request - response = client.lock_bucket_retention_policy(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.LockBucketRetentionPolicyRequest, dict]): - The request object. Request message for - [LockBucketRetentionPolicy][google.storage.v2.Storage.LockBucketRetentionPolicy]. - bucket (str): - Required. Name of a bucket. - This corresponds to the ``bucket`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Bucket: - A bucket. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [bucket] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.LockBucketRetentionPolicyRequest): - request = storage.LockBucketRetentionPolicyRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if bucket is not None: - request.bucket = bucket - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.lock_bucket_retention_policy - ] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def get_iam_policy( - self, - request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None, - *, - resource: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> policy_pb2.Policy: - r"""Gets the IAM policy for a specified bucket or managed folder. - The ``resource`` field in the request should be - ``projects/_/buckets/{bucket}`` for a bucket, or - ``projects/_/buckets/{bucket}/managedFolders/{managedFolder}`` - for a managed folder. - - **IAM Permissions**: - - Requires ``storage.buckets.getIamPolicy`` on the bucket or - ``storage.managedFolders.getIamPolicy`` IAM permission on the - managed folder. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - from google.iam.v1 import iam_policy_pb2 # type: ignore - - def sample_get_iam_policy(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = iam_policy_pb2.GetIamPolicyRequest( - resource="resource_value", - ) - - # Make the request - response = client.get_iam_policy(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]): - The request object. Request message for ``GetIamPolicy`` method. - resource (str): - REQUIRED: The resource for which the - policy is being requested. See the - operation documentation for the - appropriate value for this field. - - This corresponds to the ``resource`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.iam.v1.policy_pb2.Policy: - An Identity and Access Management (IAM) policy, which specifies access - controls for Google Cloud resources. - - A Policy is a collection of bindings. A binding binds - one or more members, or principals, to a single role. - Principals can be user accounts, service accounts, - Google groups, and domains (such as G Suite). A role - is a named list of permissions; each role can be an - IAM predefined role or a user-created custom role. - - For some types of Google Cloud resources, a binding - can also specify a condition, which is a logical - expression that allows access to a resource only if - the expression evaluates to true. A condition can add - constraints based on attributes of the request, the - resource, or both. To learn which resources support - conditions in their IAM policies, see the [IAM - documentation](https://cloud.google.com/iam/help/conditions/resource-policies). - - **JSON example:** - - :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \` - - **YAML example:** - - :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \` - - For a description of IAM and its features, see the - [IAM - documentation](https://cloud.google.com/iam/docs/). - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - if isinstance(request, dict): - # - The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. - request = iam_policy_pb2.GetIamPolicyRequest(**request) - elif not request: - # Null request, just make one. - request = iam_policy_pb2.GetIamPolicyRequest() - if resource is not None: - request.resource = resource - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.get_iam_policy] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.resource) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - routing_param_regex = re.compile( - "^(?Pprojects/[^/]+/buckets/[^/]+)(?:/.*)?$" - ) - regex_match = routing_param_regex.match(request.resource) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def set_iam_policy( - self, - request: Optional[Union[iam_policy_pb2.SetIamPolicyRequest, dict]] = None, - *, - resource: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> policy_pb2.Policy: - r"""Updates an IAM policy for the specified bucket or managed - folder. The ``resource`` field in the request should be - ``projects/_/buckets/{bucket}`` for a bucket, or - ``projects/_/buckets/{bucket}/managedFolders/{managedFolder}`` - for a managed folder. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - from google.iam.v1 import iam_policy_pb2 # type: ignore - - def sample_set_iam_policy(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = iam_policy_pb2.SetIamPolicyRequest( - resource="resource_value", - ) - - # Make the request - response = client.set_iam_policy(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]): - The request object. Request message for ``SetIamPolicy`` method. - resource (str): - REQUIRED: The resource for which the - policy is being specified. See the - operation documentation for the - appropriate value for this field. - - This corresponds to the ``resource`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.iam.v1.policy_pb2.Policy: - An Identity and Access Management (IAM) policy, which specifies access - controls for Google Cloud resources. - - A Policy is a collection of bindings. A binding binds - one or more members, or principals, to a single role. - Principals can be user accounts, service accounts, - Google groups, and domains (such as G Suite). A role - is a named list of permissions; each role can be an - IAM predefined role or a user-created custom role. - - For some types of Google Cloud resources, a binding - can also specify a condition, which is a logical - expression that allows access to a resource only if - the expression evaluates to true. A condition can add - constraints based on attributes of the request, the - resource, or both. To learn which resources support - conditions in their IAM policies, see the [IAM - documentation](https://cloud.google.com/iam/help/conditions/resource-policies). - - **JSON example:** - - :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \` - - **YAML example:** - - :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \` - - For a description of IAM and its features, see the - [IAM - documentation](https://cloud.google.com/iam/docs/). - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - if isinstance(request, dict): - # - The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. - request = iam_policy_pb2.SetIamPolicyRequest(**request) - elif not request: - # Null request, just make one. - request = iam_policy_pb2.SetIamPolicyRequest() - if resource is not None: - request.resource = resource - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.set_iam_policy] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.resource) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - routing_param_regex = re.compile( - "^(?Pprojects/[^/]+/buckets/[^/]+)(?:/.*)?$" - ) - regex_match = routing_param_regex.match(request.resource) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def test_iam_permissions( - self, - request: Optional[Union[iam_policy_pb2.TestIamPermissionsRequest, dict]] = None, - *, - resource: Optional[str] = None, - permissions: Optional[MutableSequence[str]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> iam_policy_pb2.TestIamPermissionsResponse: - r"""Tests a set of permissions on the given bucket, object, or - managed folder to see which, if any, are held by the caller. The - ``resource`` field in the request should be - ``projects/_/buckets/{bucket}`` for a bucket, - ``projects/_/buckets/{bucket}/objects/{object}`` for an object, - or - ``projects/_/buckets/{bucket}/managedFolders/{managedFolder}`` - for a managed folder. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - from google.iam.v1 import iam_policy_pb2 # type: ignore - - def sample_test_iam_permissions(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = iam_policy_pb2.TestIamPermissionsRequest( - resource="resource_value", - permissions=['permissions_value1', 'permissions_value2'], - ) - - # Make the request - response = client.test_iam_permissions(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]): - The request object. Request message for ``TestIamPermissions`` method. - resource (str): - REQUIRED: The resource for which the - policy detail is being requested. See - the operation documentation for the - appropriate value for this field. - - This corresponds to the ``resource`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - permissions (MutableSequence[str]): - The set of permissions to check for the ``resource``. - Permissions with wildcards (such as '*' or 'storage.*') - are not allowed. For more information see `IAM - Overview `__. - - This corresponds to the ``permissions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse: - Response message for TestIamPermissions method. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource, permissions] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - if isinstance(request, dict): - # - The request isn't a proto-plus wrapped type, - # so it must be constructed via keyword expansion. - request = iam_policy_pb2.TestIamPermissionsRequest(**request) - elif not request: - # Null request, just make one. - request = iam_policy_pb2.TestIamPermissionsRequest() - if resource is not None: - request.resource = resource - if permissions: - request.permissions.extend(permissions) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.test_iam_permissions] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.resource) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - routing_param_regex = re.compile( - "^(?Pprojects/[^/]+/buckets/[^/]+)/objects(?:/.*)?$" - ) - regex_match = routing_param_regex.match(request.resource) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - routing_param_regex = re.compile( - "^(?Pprojects/[^/]+/buckets/[^/]+)/managedFolders(?:/.*)?$" - ) - regex_match = routing_param_regex.match(request.resource) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_bucket( - self, - request: Optional[Union[storage.UpdateBucketRequest, dict]] = None, - *, - bucket: Optional[storage.Bucket] = None, - update_mask: Optional[field_mask_pb2.FieldMask] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Bucket: - r"""Updates a bucket. Changes to the bucket are readable immediately - after writing, but configuration changes might take time to - propagate. This method supports ``patch`` semantics. - - **IAM Permissions**: - - Requires ``storage.buckets.update`` IAM permission on the - bucket. Additionally, to enable specific bucket features, the - authenticated user must have the following permissions: - - - To set bucket IP filtering rules: - ``storage.buckets.setIpFilter`` - - To update public access prevention policies or access control - lists (ACLs): ``storage.buckets.setIamPolicy`` - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_update_bucket(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.UpdateBucketRequest( - ) - - # Make the request - response = client.update_bucket(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.UpdateBucketRequest, dict]): - The request object. Request for - [UpdateBucket][google.storage.v2.Storage.UpdateBucket] - method. - bucket (google.cloud._storage_v2.types.Bucket): - Required. The bucket to update. The bucket's ``name`` - field is used to identify the bucket. - - This corresponds to the ``bucket`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Required. List of fields to be updated. - - To specify ALL fields, equivalent to the JSON API's - "update" function, specify a single field with the value - ``*``. Note: not recommended. If a new field is - introduced at a later time, an older client updating - with the ``*`` might accidentally reset the new field's - value. - - Not specifying any fields is an error. - - This corresponds to the ``update_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Bucket: - A bucket. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [bucket, update_mask] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.UpdateBucketRequest): - request = storage.UpdateBucketRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if bucket is not None: - request.bucket = bucket - if update_mask is not None: - request.update_mask = update_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.update_bucket] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.bucket.name) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def compose_object( - self, - request: Optional[Union[storage.ComposeObjectRequest, dict]] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Object: - r"""Concatenates a list of existing objects into a new object in the - same bucket. The existing source objects are unaffected by this - operation. - - **IAM Permissions**: - - Requires the ``storage.objects.create`` and - ``storage.objects.get`` IAM permissions to use this method. If - the new composite object overwrites an existing object, the - authenticated user must also have the ``storage.objects.delete`` - permission. If the request body includes the retention property, - the authenticated user must also have the - ``storage.objects.setRetention`` IAM permission. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_compose_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.ComposeObjectRequest( - ) - - # Make the request - response = client.compose_object(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.ComposeObjectRequest, dict]): - The request object. Request message for - [ComposeObject][google.storage.v2.Storage.ComposeObject]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Object: - An object. - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.ComposeObjectRequest): - request = storage.ComposeObjectRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.compose_object] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.destination.bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def delete_object( - self, - request: Optional[Union[storage.DeleteObjectRequest, dict]] = None, - *, - bucket: Optional[str] = None, - object_: Optional[str] = None, - generation: Optional[int] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Deletes an object and its metadata. Deletions are permanent if - versioning is not enabled for the bucket, or if the generation - parameter is used, or if soft delete is not enabled for the - bucket. When this API is used to delete an object from a bucket - that has soft delete policy enabled, the object becomes soft - deleted, and the ``softDeleteTime`` and ``hardDeleteTime`` - properties are set on the object. This API cannot be used to - permanently delete soft-deleted objects. Soft-deleted objects - are permanently deleted according to their ``hardDeleteTime``. - - You can use the - [``RestoreObject``][google.storage.v2.Storage.RestoreObject] API - to restore soft-deleted objects until the soft delete retention - period has passed. - - **IAM Permissions**: - - Requires ``storage.objects.delete`` IAM permission on the - bucket. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_delete_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.DeleteObjectRequest( - bucket="bucket_value", - object_="object__value", - ) - - # Make the request - client.delete_object(request=request) - - Args: - request (Union[google.cloud._storage_v2.types.DeleteObjectRequest, dict]): - The request object. Request message for deleting an - object. - bucket (str): - Required. Name of the bucket in which - the object resides. - - This corresponds to the ``bucket`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - object_ (str): - Required. The name of the finalized object to delete. - Note: If you want to delete an unfinalized resumable - upload please use ``CancelResumableWrite``. - - This corresponds to the ``object_`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - generation (int): - Optional. If present, permanently - deletes a specific revision of this - object (as opposed to the latest - version, the default). - - This corresponds to the ``generation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [bucket, object_, generation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.DeleteObjectRequest): - request = storage.DeleteObjectRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if bucket is not None: - request.bucket = bucket - if object_ is not None: - request.object_ = object_ - if generation is not None: - request.generation = generation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.delete_object] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def restore_object( - self, - request: Optional[Union[storage.RestoreObjectRequest, dict]] = None, - *, - bucket: Optional[str] = None, - object_: Optional[str] = None, - generation: Optional[int] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Object: - r"""Restores a soft-deleted object. When a soft-deleted object is - restored, a new copy of that object is created in the same - bucket and inherits the same metadata as the soft-deleted - object. The inherited metadata is the metadata that existed when - the original object became soft deleted, with the following - exceptions: - - - The ``createTime`` of the new object is set to the time at - which the soft-deleted object was restored. - - The ``softDeleteTime`` and ``hardDeleteTime`` values are - cleared. - - A new generation is assigned and the metageneration is reset - to 1. - - If the soft-deleted object was in a bucket that had Autoclass - enabled, the new object is restored to Standard storage. - - The restored object inherits the bucket's default object ACL, - unless ``copySourceAcl`` is ``true``. - - If a live object using the same name already exists in the - bucket and becomes overwritten, the live object becomes a - noncurrent object if Object Versioning is enabled on the bucket. - If Object Versioning is not enabled, the live object becomes - soft deleted. - - **IAM Permissions**: - - Requires the following IAM permissions to use this method: - - - ``storage.objects.restore`` - - ``storage.objects.create`` - - ``storage.objects.delete`` (only required if overwriting an - existing object) - - ``storage.objects.getIamPolicy`` (only required if - ``projection`` is ``full`` and the relevant bucket has uniform - bucket-level access disabled) - - ``storage.objects.setIamPolicy`` (only required if - ``copySourceAcl`` is ``true`` and the relevant bucket has - uniform bucket-level access disabled) - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_restore_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.RestoreObjectRequest( - bucket="bucket_value", - object_="object__value", - generation=1068, - ) - - # Make the request - response = client.restore_object(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.RestoreObjectRequest, dict]): - The request object. Request message for - [RestoreObject][google.storage.v2.Storage.RestoreObject]. - ``bucket``, ``object``, and ``generation`` **must** be - set. - bucket (str): - Required. Name of the bucket in which - the object resides. - - This corresponds to the ``bucket`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - object_ (str): - Required. The name of the object to - restore. - - This corresponds to the ``object_`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - generation (int): - Required. The specific revision of - the object to restore. - - This corresponds to the ``generation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Object: - An object. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [bucket, object_, generation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.RestoreObjectRequest): - request = storage.RestoreObjectRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if bucket is not None: - request.bucket = bucket - if object_ is not None: - request.object_ = object_ - if generation is not None: - request.generation = generation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.restore_object] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def cancel_resumable_write( - self, - request: Optional[Union[storage.CancelResumableWriteRequest, dict]] = None, - *, - upload_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.CancelResumableWriteResponse: - r"""Cancels an in-progress resumable upload. - - Any attempts to write to the resumable upload after - cancelling the upload fail. - - The behavior for any in-progress write operations is not - guaranteed; they could either complete before the - cancellation or fail if the cancellation completes - first. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_cancel_resumable_write(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.CancelResumableWriteRequest( - upload_id="upload_id_value", - ) - - # Make the request - response = client.cancel_resumable_write(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.CancelResumableWriteRequest, dict]): - The request object. Request message for - [CancelResumableWrite][google.storage.v2.Storage.CancelResumableWrite]. - upload_id (str): - Required. The upload_id of the resumable upload to - cancel. This should be copied from the ``upload_id`` - field of ``StartResumableWriteResponse``. - - This corresponds to the ``upload_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.CancelResumableWriteResponse: - Empty response message for canceling - an in-progress resumable upload, is - extended as needed. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [upload_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.CancelResumableWriteRequest): - request = storage.CancelResumableWriteRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if upload_id is not None: - request.upload_id = upload_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.cancel_resumable_write] - - header_params = {} - - routing_param_regex = re.compile( - "^(?Pprojects/[^/]+/buckets/[^/]+)(?:/.*)?$" - ) - regex_match = routing_param_regex.match(request.upload_id) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def get_object( - self, - request: Optional[Union[storage.GetObjectRequest, dict]] = None, - *, - bucket: Optional[str] = None, - object_: Optional[str] = None, - generation: Optional[int] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Object: - r"""Retrieves object metadata. - - **IAM Permissions**: - - Requires ``storage.objects.get`` IAM permission on the bucket. - To return object ACLs, the authenticated user must also have the - ``storage.objects.getIamPolicy`` permission. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_get_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.GetObjectRequest( - bucket="bucket_value", - object_="object__value", - ) - - # Make the request - response = client.get_object(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.GetObjectRequest, dict]): - The request object. Request message for - [GetObject][google.storage.v2.Storage.GetObject]. - bucket (str): - Required. Name of the bucket in which - the object resides. - - This corresponds to the ``bucket`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - object_ (str): - Required. Name of the object. - This corresponds to the ``object_`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - generation (int): - Optional. If present, selects a - specific revision of this object (as - opposed to the latest version, the - default). - - This corresponds to the ``generation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Object: - An object. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [bucket, object_, generation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.GetObjectRequest): - request = storage.GetObjectRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if bucket is not None: - request.bucket = bucket - if object_ is not None: - request.object_ = object_ - if generation is not None: - request.generation = generation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.get_object] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def read_object( - self, - request: Optional[Union[storage.ReadObjectRequest, dict]] = None, - *, - bucket: Optional[str] = None, - object_: Optional[str] = None, - generation: Optional[int] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> Iterable[storage.ReadObjectResponse]: - r"""Retrieves object data. - - **IAM Permissions**: - - Requires ``storage.objects.get`` IAM permission on the bucket. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_read_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.ReadObjectRequest( - bucket="bucket_value", - object_="object__value", - ) - - # Make the request - stream = client.read_object(request=request) - - # Handle the response - for response in stream: - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.ReadObjectRequest, dict]): - The request object. Request message for - [ReadObject][google.storage.v2.Storage.ReadObject]. - bucket (str): - Required. The name of the bucket - containing the object to read. - - This corresponds to the ``bucket`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - object_ (str): - Required. The name of the object to - read. - - This corresponds to the ``object_`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - generation (int): - Optional. If present, selects a - specific revision of this object (as - opposed to the latest version, the - default). - - This corresponds to the ``generation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - Iterable[google.cloud._storage_v2.types.ReadObjectResponse]: - Response message for - [ReadObject][google.storage.v2.Storage.ReadObject]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [bucket, object_, generation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.ReadObjectRequest): - request = storage.ReadObjectRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if bucket is not None: - request.bucket = bucket - if object_ is not None: - request.object_ = object_ - if generation is not None: - request.generation = generation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.read_object] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def bidi_read_object( - self, - requests: Optional[Iterator[storage.BidiReadObjectRequest]] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> Iterable[storage.BidiReadObjectResponse]: - r"""Reads an object's data. - - This bi-directional API reads data from an object, allowing you - to request multiple data ranges within a single stream, even - across several messages. If an error occurs with any request, - the stream closes with a relevant error code. Since you can have - multiple outstanding requests, the error response includes a - ``BidiReadObjectRangesError`` field detailing the specific error - for each pending ``read_id``. - - **IAM Permissions**: - - Requires ``storage.objects.get`` IAM permission on the bucket. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_bidi_read_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.BidiReadObjectRequest( - ) - - # This method expects an iterator which contains - # 'storage_v2.BidiReadObjectRequest' objects - # Here we create a generator that yields a single `request` for - # demonstrative purposes. - requests = [request] - - def request_generator(): - for request in requests: - yield request - - # Make the request - stream = client.bidi_read_object(requests=request_generator()) - - # Handle the response - for response in stream: - print(response) - - Args: - requests (Iterator[google.cloud._storage_v2.types.BidiReadObjectRequest]): - The request object iterator. Request message for - [BidiReadObject][google.storage.v2.Storage.BidiReadObject]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - Iterable[google.cloud._storage_v2.types.BidiReadObjectResponse]: - Response message for - [BidiReadObject][google.storage.v2.Storage.BidiReadObject]. - - """ - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.bidi_read_object] - - header_params = {} - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - requests, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_object( - self, - request: Optional[Union[storage.UpdateObjectRequest, dict]] = None, - *, - object_: Optional[storage.Object] = None, - update_mask: Optional[field_mask_pb2.FieldMask] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Object: - r"""Updates an object's metadata. Equivalent to JSON API's - ``storage.objects.patch`` method. - - **IAM Permissions**: - - Requires ``storage.objects.update`` IAM permission on the - bucket. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_update_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.UpdateObjectRequest( - ) - - # Make the request - response = client.update_object(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.UpdateObjectRequest, dict]): - The request object. Request message for - [UpdateObject][google.storage.v2.Storage.UpdateObject]. - object_ (google.cloud._storage_v2.types.Object): - Required. The object to update. - The object's bucket and name fields are - used to identify the object to update. - If present, the object's generation - field selects a specific revision of - this object whose metadata should be - updated. Otherwise, assumes the live - version of the object. - - This corresponds to the ``object_`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Required. List of fields to be updated. - - To specify ALL fields, equivalent to the JSON API's - "update" function, specify a single field with the value - ``*``. Note: not recommended. If a new field is - introduced at a later time, an older client updating - with the ``*`` might accidentally reset the new field's - value. - - Not specifying any fields is an error. - - This corresponds to the ``update_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Object: - An object. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [object_, update_mask] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.UpdateObjectRequest): - request = storage.UpdateObjectRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if object_ is not None: - request.object_ = object_ - if update_mask is not None: - request.update_mask = update_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.update_object] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.object.bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def write_object( - self, - requests: Optional[Iterator[storage.WriteObjectRequest]] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.WriteObjectResponse: - r"""Stores a new object and metadata. - - An object can be written either in a single message stream or in - a resumable sequence of message streams. To write using a single - stream, the client should include in the first message of the - stream an ``WriteObjectSpec`` describing the destination bucket, - object, and any preconditions. Additionally, the final message - must set 'finish_write' to true, or else it is an error. - - For a resumable write, the client should instead call - ``StartResumableWrite()``, populating a ``WriteObjectSpec`` into - that request. They should then attach the returned ``upload_id`` - to the first message of each following call to ``WriteObject``. - If the stream is closed before finishing the upload (either - explicitly by the client or due to a network error or an error - response from the server), the client should do as follows: - - - Check the result Status of the stream, to determine if writing - can be resumed on this stream or must be restarted from - scratch (by calling ``StartResumableWrite()``). The resumable - errors are ``DEADLINE_EXCEEDED``, ``INTERNAL``, and - ``UNAVAILABLE``. For each case, the client should use binary - exponential backoff before retrying. Additionally, writes can - be resumed after ``RESOURCE_EXHAUSTED`` errors, but only after - taking appropriate measures, which might include reducing - aggregate send rate across clients and/or requesting a quota - increase for your project. - - If the call to ``WriteObject`` returns ``ABORTED``, that - indicates concurrent attempts to update the resumable write, - caused either by multiple racing clients or by a single client - where the previous request was timed out on the client side - but nonetheless reached the server. In this case the client - should take steps to prevent further concurrent writes. For - example, increase the timeouts and stop using more than one - process to perform the upload. Follow the steps below for - resuming the upload. - - For resumable errors, the client should call - ``QueryWriteStatus()`` and then continue writing from the - returned ``persisted_size``. This might be less than the - amount of data the client previously sent. Note also that it - is acceptable to send data starting at an offset earlier than - the returned ``persisted_size``; in this case, the service - skips data at offsets that were already persisted (without - checking that it matches the previously written data), and - write only the data starting from the persisted offset. Even - though the data isn't written, it might still incur a - performance cost over resuming at the correct write offset. - This behavior can make client-side handling simpler in some - cases. - - Clients must only send data that is a multiple of 256 KiB per - message, unless the object is being finished with - ``finish_write`` set to ``true``. - - The service does not view the object as complete until the - client has sent a ``WriteObjectRequest`` with ``finish_write`` - set to ``true``. Sending any requests on a stream after sending - a request with ``finish_write`` set to ``true`` causes an error. - The client must check the response it receives to determine how - much data the service is able to commit and whether the service - views the object as complete. - - Attempting to resume an already finalized object results in an - ``OK`` status, with a ``WriteObjectResponse`` containing the - finalized object's metadata. - - Alternatively, you can use the ``BidiWriteObject`` operation to - write an object with controls over flushing and the ability to - fetch the ability to determine the current persisted size. - - **IAM Permissions**: - - Requires ``storage.objects.create`` IAM permission on the - bucket. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_write_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.WriteObjectRequest( - upload_id="upload_id_value", - write_offset=1297, - ) - - # This method expects an iterator which contains - # 'storage_v2.WriteObjectRequest' objects - # Here we create a generator that yields a single `request` for - # demonstrative purposes. - requests = [request] - - def request_generator(): - for request in requests: - yield request - - # Make the request - response = client.write_object(requests=request_generator()) - - # Handle the response - print(response) - - Args: - requests (Iterator[google.cloud._storage_v2.types.WriteObjectRequest]): - The request object iterator. Request message for - [WriteObject][google.storage.v2.Storage.WriteObject]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.WriteObjectResponse: - Response message for - [WriteObject][google.storage.v2.Storage.WriteObject]. - - """ - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.write_object] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - requests, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def bidi_write_object( - self, - requests: Optional[Iterator[storage.BidiWriteObjectRequest]] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> Iterable[storage.BidiWriteObjectResponse]: - r"""Stores a new object and metadata. - - This is similar to the ``WriteObject`` call with the added - support for manual flushing of persisted state, and the ability - to determine current persisted size without closing the stream. - - The client might specify one or both of the ``state_lookup`` and - ``flush`` fields in each ``BidiWriteObjectRequest``. If - ``flush`` is specified, the data written so far is persisted to - storage. If ``state_lookup`` is specified, the service responds - with a ``BidiWriteObjectResponse`` that contains the persisted - size. If both ``flush`` and ``state_lookup`` are specified, the - flush always occurs before a ``state_lookup``, so that both - might be set in the same request and the returned state is the - state of the object post-flush. When the stream is closed, a - ``BidiWriteObjectResponse`` is always sent to the client, - regardless of the value of ``state_lookup``. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_bidi_write_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.BidiWriteObjectRequest( - upload_id="upload_id_value", - write_offset=1297, - ) - - # This method expects an iterator which contains - # 'storage_v2.BidiWriteObjectRequest' objects - # Here we create a generator that yields a single `request` for - # demonstrative purposes. - requests = [request] - - def request_generator(): - for request in requests: - yield request - - # Make the request - stream = client.bidi_write_object(requests=request_generator()) - - # Handle the response - for response in stream: - print(response) - - Args: - requests (Iterator[google.cloud._storage_v2.types.BidiWriteObjectRequest]): - The request object iterator. Request message for - [BidiWriteObject][google.storage.v2.Storage.BidiWriteObject]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - Iterable[google.cloud._storage_v2.types.BidiWriteObjectResponse]: - Response message for BidiWriteObject. - """ - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.bidi_write_object] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - requests, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_objects( - self, - request: Optional[Union[storage.ListObjectsRequest, dict]] = None, - *, - parent: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListObjectsPager: - r"""Retrieves a list of objects matching the criteria. - - **IAM Permissions**: - - The authenticated user requires ``storage.objects.list`` IAM - permission to use this method. To return object ACLs, the - authenticated user must also have the - ``storage.objects.getIamPolicy`` permission. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_list_objects(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.ListObjectsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_objects(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.ListObjectsRequest, dict]): - The request object. Request message for - [ListObjects][google.storage.v2.Storage.ListObjects]. - parent (str): - Required. Name of the bucket in which - to look for objects. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.services.storage.pagers.ListObjectsPager: - The result of a call to - Objects.ListObjects - Iterating over this object will yield - results and resolve additional pages - automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [parent] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.ListObjectsRequest): - request = storage.ListObjectsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_objects] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.parent) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListObjectsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def rewrite_object( - self, - request: Optional[Union[storage.RewriteObjectRequest, dict]] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.RewriteResponse: - r"""Rewrites a source object to a destination object. - Optionally overrides metadata. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_rewrite_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.RewriteObjectRequest( - destination_name="destination_name_value", - destination_bucket="destination_bucket_value", - source_bucket="source_bucket_value", - source_object="source_object_value", - ) - - # Make the request - response = client.rewrite_object(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.RewriteObjectRequest, dict]): - The request object. Request message for - [RewriteObject][google.storage.v2.Storage.RewriteObject]. - If the source object is encrypted using a - Customer-Supplied Encryption Key the key information - must be provided in the - ``copy_source_encryption_algorithm``, - ``copy_source_encryption_key_bytes``, and - ``copy_source_encryption_key_sha256_bytes`` fields. If - the destination object should be encrypted the keying - information should be provided in the - ``encryption_algorithm``, ``encryption_key_bytes``, and - ``encryption_key_sha256_bytes`` fields of the - ``common_object_request_params.customer_encryption`` - field. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.RewriteResponse: - A rewrite response. - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.RewriteObjectRequest): - request = storage.RewriteObjectRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.rewrite_object] - - header_params = {} - - if request.source_bucket: - header_params["source_bucket"] = request.source_bucket - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.destination_bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def start_resumable_write( - self, - request: Optional[Union[storage.StartResumableWriteRequest, dict]] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.StartResumableWriteResponse: - r"""Starts a resumable write operation. This method is part of the - Resumable upload feature. This allows you to upload large - objects in multiple chunks, which is more resilient to network - interruptions than a single upload. The validity duration of the - write operation, and the consequences of it becoming invalid, - are service-dependent. - - **IAM Permissions**: - - Requires ``storage.objects.create`` IAM permission on the - bucket. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_start_resumable_write(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.StartResumableWriteRequest( - ) - - # Make the request - response = client.start_resumable_write(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.StartResumableWriteRequest, dict]): - The request object. Request message for - [StartResumableWrite][google.storage.v2.Storage.StartResumableWrite]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.StartResumableWriteResponse: - Response object for - [StartResumableWrite][google.storage.v2.Storage.StartResumableWrite]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.StartResumableWriteRequest): - request = storage.StartResumableWriteRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.start_resumable_write] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match( - request.write_object_spec.resource.bucket - ) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def query_write_status( - self, - request: Optional[Union[storage.QueryWriteStatusRequest, dict]] = None, - *, - upload_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.QueryWriteStatusResponse: - r"""Determines the ``persisted_size`` of an object that is being - written. This method is part of the resumable upload feature. - The returned value is the size of the object that has been - persisted so far. The value can be used as the ``write_offset`` - for the next ``Write()`` call. - - If the object does not exist, meaning if it was deleted, or the - first ``Write()`` has not yet reached the service, this method - returns the error ``NOT_FOUND``. - - This method is useful for clients that buffer data and need to - know which data can be safely evicted. The client can call - ``QueryWriteStatus()`` at any time to determine how much data - has been logged for this object. For any sequence of - ``QueryWriteStatus()`` calls for a given object name, the - sequence of returned ``persisted_size`` values are - non-decreasing. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_query_write_status(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.QueryWriteStatusRequest( - upload_id="upload_id_value", - ) - - # Make the request - response = client.query_write_status(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.QueryWriteStatusRequest, dict]): - The request object. Request object for - [QueryWriteStatus][google.storage.v2.Storage.QueryWriteStatus]. - upload_id (str): - Required. The name of the resume - token for the object whose write status - is being requested. - - This corresponds to the ``upload_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.QueryWriteStatusResponse: - Response object for - [QueryWriteStatus][google.storage.v2.Storage.QueryWriteStatus]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [upload_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.QueryWriteStatusRequest): - request = storage.QueryWriteStatusRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if upload_id is not None: - request.upload_id = upload_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.query_write_status] - - header_params = {} - - routing_param_regex = re.compile( - "^(?Pprojects/[^/]+/buckets/[^/]+)(?:/.*)?$" - ) - regex_match = routing_param_regex.match(request.upload_id) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def move_object( - self, - request: Optional[Union[storage.MoveObjectRequest, dict]] = None, - *, - bucket: Optional[str] = None, - source_object: Optional[str] = None, - destination_object: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> storage.Object: - r"""Moves the source object to the destination object in the same - bucket. This operation moves a source object to a destination - object in the same bucket by renaming the object. The move - itself is an atomic transaction, ensuring all steps either - complete successfully or no changes are made. - - **IAM Permissions**: - - Requires the following IAM permissions to use this method: - - - ``storage.objects.move`` - - ``storage.objects.create`` - - ``storage.objects.delete`` (only required if overwriting an - existing object) - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import storage_v2 - - def sample_move_object(): - # Create a client - client = storage_v2.StorageClient() - - # Initialize request argument(s) - request = storage_v2.MoveObjectRequest( - bucket="bucket_value", - source_object="source_object_value", - destination_object="destination_object_value", - ) - - # Make the request - response = client.move_object(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud._storage_v2.types.MoveObjectRequest, dict]): - The request object. Request message for - [MoveObject][google.storage.v2.Storage.MoveObject]. - bucket (str): - Required. Name of the bucket in which - the object resides. - - This corresponds to the ``bucket`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - source_object (str): - Required. Name of the source object. - This corresponds to the ``source_object`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - destination_object (str): - Required. Name of the destination - object. - - This corresponds to the ``destination_object`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud._storage_v2.types.Object: - An object. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [bucket, source_object, destination_object] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, storage.MoveObjectRequest): - request = storage.MoveObjectRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if bucket is not None: - request.bucket = bucket - if source_object is not None: - request.source_object = source_object - if destination_object is not None: - request.destination_object = destination_object - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.move_object] - - header_params = {} - - routing_param_regex = re.compile("^(?P.*)$") - regex_match = routing_param_regex.match(request.bucket) - if regex_match and regex_match.group("bucket"): - header_params["bucket"] = regex_match.group("bucket") - - if header_params: - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(header_params), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "StorageClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("StorageClient",) diff --git a/google/cloud/_storage_v2/services/storage/transports/grpc.py b/google/cloud/_storage_v2/services/storage/transports/grpc.py index fae2d7949..6497959d7 100644 --- a/google/cloud/_storage_v2/services/storage/transports/grpc.py +++ b/google/cloud/_storage_v2/services/storage/transports/grpc.py @@ -946,8 +946,9 @@ def bidi_read_object( across several messages. If an error occurs with any request, the stream closes with a relevant error code. Since you can have multiple outstanding requests, the error response includes a - ``BidiReadObjectRangesError`` field detailing the specific error - for each pending ``read_id``. + ``BidiReadObjectError`` proto in its ``details`` field, + reporting the specific error, if any, for each pending + ``read_id``. **IAM Permissions**: diff --git a/google/cloud/_storage_v2/services/storage/transports/grpc_asyncio.py b/google/cloud/_storage_v2/services/storage/transports/grpc_asyncio.py index be54eb3b0..1c7743a72 100644 --- a/google/cloud/_storage_v2/services/storage/transports/grpc_asyncio.py +++ b/google/cloud/_storage_v2/services/storage/transports/grpc_asyncio.py @@ -971,8 +971,9 @@ def bidi_read_object( across several messages. If an error occurs with any request, the stream closes with a relevant error code. Since you can have multiple outstanding requests, the error response includes a - ``BidiReadObjectRangesError`` field detailing the specific error - for each pending ``read_id``. + ``BidiReadObjectError`` proto in its ``details`` field, + reporting the specific error, if any, for each pending + ``read_id``. **IAM Permissions**: diff --git a/google/cloud/_storage_v2/types/storage.py b/google/cloud/_storage_v2/types/storage.py index 8602610be..d1a7c5a36 100644 --- a/google/cloud/_storage_v2/types/storage.py +++ b/google/cloud/_storage_v2/types/storage.py @@ -489,6 +489,11 @@ class ComposeObjectRequest(proto.Message): Optional. The checksums of the complete object. This is validated against the combined checksums of the component objects. + delete_source_objects (bool): + Whether the source objects should be deleted + in the compose request. + + This field is a member of `oneof`_ ``_delete_source_objects``. """ class SourceObject(proto.Message): @@ -580,6 +585,11 @@ class ObjectPreconditions(proto.Message): number=10, message="ObjectChecksums", ) + delete_source_objects: bool = proto.Field( + proto.BOOL, + number=11, + optional=True, + ) class DeleteObjectRequest(proto.Message): @@ -1460,18 +1470,18 @@ class ReadRange(proto.Message): ``ReadObjectRequest`` with ``read_offset`` = -5 and ``read_length`` = 3 would return bytes 10 through 12 of the object. Requesting a negative offset with magnitude larger - than the size of the object returns the entire object. A - ``read_offset`` larger than the size of the object results - in an ``OutOfRange`` error. + than the size of the object is equivalent to ``read_offset`` + = 0. A ``read_offset`` larger than the size of the object + results in an ``OutOfRange`` error. read_length (int): Optional. The maximum number of data bytes the server is allowed to return across all response messages with the same ``read_id``. A ``read_length`` of zero indicates to read until the resource end, and a negative ``read_length`` - causes an error. If the stream returns fewer bytes than - allowed by the ``read_length`` and no error occurred, the - stream includes all data from the ``read_offset`` to the - resource end. + causes an ``OutOfRange`` error. If the stream returns fewer + bytes than allowed by the ``read_length`` and no error + occurred, the stream includes all data from the + ``read_offset`` to the resource end. read_id (int): Required. Read identifier provided by the client. When the client issues more than one outstanding ``ReadRange`` on the @@ -4364,7 +4374,10 @@ class ObjectContexts(proto.Message): Attributes: custom (MutableMapping[str, google.cloud._storage_v2.types.ObjectCustomContextPayload]): - Optional. User-defined object contexts. + Optional. User-defined object contexts. The maximum key or + value size is ``256`` characters. The maximum number of + entries is ``50``. The maximum total serialized size of all + entries is ``25KiB``. """ custom: MutableMapping[str, "ObjectCustomContextPayload"] = proto.MapField( diff --git a/noxfile.py b/noxfile.py index 77823d28d..a00b72040 100644 --- a/noxfile.py +++ b/noxfile.py @@ -67,8 +67,6 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - # Pin flake8 to 6.0.0 - # See https://github.com/googleapis/python-storage/issues/1102 session.install("flake8", BLACK_VERSION) session.run( "black", diff --git a/testing/constraints-3.14.txt b/testing/constraints-3.14.txt index 62739fc5d..2ae5a677e 100644 --- a/testing/constraints-3.14.txt +++ b/testing/constraints-3.14.txt @@ -7,7 +7,7 @@ # Then this file should have google-cloud-foo>=1 google-api-core>=2 google-auth>=2 -grpcio>=1.75.1 +grpcio>=1 proto-plus>=1 protobuf>=6 grpc-google-iam-v1>=0 diff --git a/tests/unit/gapic/storage_v2/test_storage.py b/tests/unit/gapic/storage_v2/test_storage.py index 7b6340aa7..20b680341 100644 --- a/tests/unit/gapic/storage_v2/test_storage.py +++ b/tests/unit/gapic/storage_v2/test_storage.py @@ -148,19 +148,12 @@ def test__read_environment_variables(): with mock.patch.dict( os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} ): - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with pytest.raises(ValueError) as excinfo: - StorageClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - else: - assert StorageClient._read_environment_variables() == ( - False, - "auto", - None, - ) + with pytest.raises(ValueError) as excinfo: + StorageClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): assert StorageClient._read_environment_variables() == (False, "never", None) @@ -183,105 +176,6 @@ def test__read_environment_variables(): assert StorageClient._read_environment_variables() == (False, "auto", "foo.com") -def test_use_client_cert_effective(): - # Test case 1: Test when `should_use_client_cert` returns True. - # We mock the `should_use_client_cert` function to simulate a scenario where - # the google-auth library supports automatic mTLS and determines that a - # client certificate should be used. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch( - "google.auth.transport.mtls.should_use_client_cert", return_value=True - ): - assert StorageClient._use_client_cert_effective() is True - - # Test case 2: Test when `should_use_client_cert` returns False. - # We mock the `should_use_client_cert` function to simulate a scenario where - # the google-auth library supports automatic mTLS and determines that a - # client certificate should NOT be used. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch( - "google.auth.transport.mtls.should_use_client_cert", return_value=False - ): - assert StorageClient._use_client_cert_effective() is False - - # Test case 3: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert StorageClient._use_client_cert_effective() is True - - # Test case 4: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} - ): - assert StorageClient._use_client_cert_effective() is False - - # Test case 5: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): - assert StorageClient._use_client_cert_effective() is True - - # Test case 6: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} - ): - assert StorageClient._use_client_cert_effective() is False - - # Test case 7: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): - assert StorageClient._use_client_cert_effective() is True - - # Test case 8: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} - ): - assert StorageClient._use_client_cert_effective() is False - - # Test case 9: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. - # In this case, the method should return False, which is the default value. - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, clear=True): - assert StorageClient._use_client_cert_effective() is False - - # Test case 10: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. - # The method should raise a ValueError as the environment variable must be either - # "true" or "false". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} - ): - with pytest.raises(ValueError): - StorageClient._use_client_cert_effective() - - # Test case 11: Test when `should_use_client_cert` is available and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. - # The method should return False as the environment variable is set to an invalid value. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} - ): - assert StorageClient._use_client_cert_effective() is False - - # Test case 12: Test when `should_use_client_cert` is available and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, - # the GOOGLE_API_CONFIG environment variable is unset. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): - with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): - assert StorageClient._use_client_cert_effective() is False - - def test__get_client_cert_source(): mock_provided_cert_source = mock.Mock() mock_default_cert_source = mock.Mock() @@ -621,6 +515,17 @@ def test_storage_client_client_options(client_class, transport_class, transport_ == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + # Check the case quota_project_id is provided options = client_options.ClientOptions(quota_project_id="octopus") with mock.patch.object(transport_class, "__init__") as patched: @@ -828,119 +733,6 @@ def test_storage_client_get_mtls_endpoint_and_cert_source(client_class): assert api_endpoint == mock_api_endpoint assert cert_source is None - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported". - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. - test_cases = [ - ( - # With workloads present in config, mTLS is enabled. - { - "version": 1, - "cert_configs": { - "workload": { - "cert_path": "path/to/cert/file", - "key_path": "path/to/key/file", - } - }, - }, - mock_client_cert_source, - ), - ( - # With workloads not present in config, mTLS is disabled. - { - "version": 1, - "cert_configs": {}, - }, - None, - ), - ] - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - for config_data, expected_cert_source in test_cases: - env = os.environ.copy() - env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) - with mock.patch.dict(os.environ, env, clear=True): - config_filename = "mock_certificate_config.json" - config_file_content = json.dumps(config_data) - m = mock.mock_open(read_data=config_file_content) - with mock.patch("builtins.open", m): - with mock.patch.dict( - os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} - ): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is expected_cert_source - - # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). - test_cases = [ - ( - # With workloads present in config, mTLS is enabled. - { - "version": 1, - "cert_configs": { - "workload": { - "cert_path": "path/to/cert/file", - "key_path": "path/to/key/file", - } - }, - }, - mock_client_cert_source, - ), - ( - # With workloads not present in config, mTLS is disabled. - { - "version": 1, - "cert_configs": {}, - }, - None, - ), - ] - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - for config_data, expected_cert_source in test_cases: - env = os.environ.copy() - env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") - with mock.patch.dict(os.environ, env, clear=True): - config_filename = "mock_certificate_config.json" - config_file_content = json.dumps(config_data) - m = mock.mock_open(read_data=config_file_content) - with mock.patch("builtins.open", m): - with mock.patch.dict( - os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} - ): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is expected_cert_source - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() @@ -991,6 +783,18 @@ def test_storage_client_get_mtls_endpoint_and_cert_source(client_class): == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + @pytest.mark.parametrize("client_class", [StorageClient, StorageAsyncClient]) @mock.patch.object(