Skip to content

Commit 85cbb75

Browse files
speedstorm1copybara-github
authored andcommitted
feat: add support of google-cloud-storage v3 dependency
PiperOrigin-RevId: 825277520
1 parent 4618729 commit 85cbb75

26 files changed

+169
-83
lines changed

google/cloud/aiplatform/utils/gcs_utils.py

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,19 @@
1717

1818
import datetime
1919
import glob
20+
21+
# Version detection and compatibility layer for google-cloud-storage v2/v3
22+
from importlib.metadata import version as get_version
2023
import logging
2124
import os
2225
import pathlib
2326
import tempfile
2427
from typing import Optional, TYPE_CHECKING
28+
import warnings
2529

2630
from google.auth import credentials as auth_credentials
2731
from google.cloud import storage
32+
from packaging.version import Version
2833

2934
from google.cloud.aiplatform import initializer
3035
from google.cloud.aiplatform.utils import resource_manager_utils
@@ -35,6 +40,66 @@
3540
_logger = logging.getLogger(__name__)
3641

3742

43+
# Detect google-cloud-storage version once at module load
44+
try:
45+
_GCS_VERSION = Version(get_version("google-cloud-storage"))
46+
except Exception:
47+
# Fallback if version detection fails (should not happen in normal use)
48+
_GCS_VERSION = Version("2.0.0")
49+
50+
_USE_FROM_URI = _GCS_VERSION >= Version("3.0.0")
51+
52+
# Warn users on v2 about upcoming deprecation
53+
if _GCS_VERSION < Version("3.0.0"):
54+
warnings.warn(
55+
"Support for google-cloud-storage < 3.0.0 will be removed in a future"
56+
" version of google-cloud-aiplatform. Please upgrade to"
57+
" google-cloud-storage >= 3.0.0.",
58+
FutureWarning,
59+
stacklevel=2,
60+
)
61+
62+
63+
def blob_from_uri(uri: str, client: storage.Client) -> storage.Blob:
64+
"""Create a Blob from a GCS URI, compatible with v2 and v3.
65+
66+
This function provides compatibility across google-cloud-storage versions:
67+
- v3.x: Uses Blob.from_uri()
68+
- v2.x: Uses Blob.from_string() (deprecated in v3)
69+
70+
Args:
71+
uri: GCS URI (e.g., 'gs://bucket/path/to/blob')
72+
client: Storage client instance
73+
74+
Returns:
75+
storage.Blob: Blob instance
76+
"""
77+
if _USE_FROM_URI:
78+
return storage.Blob.from_uri(uri, client=client)
79+
else:
80+
return storage.Blob.from_string(uri, client=client)
81+
82+
83+
def bucket_from_uri(uri: str, client: storage.Client) -> storage.Bucket:
84+
"""Create a Bucket from a GCS URI, compatible with v2 and v3.
85+
86+
This function provides compatibility across google-cloud-storage versions:
87+
- v3.x: Uses Bucket.from_uri()
88+
- v2.x: Uses Bucket.from_string() (deprecated in v3)
89+
90+
Args:
91+
uri: GCS bucket URI (e.g., 'gs://bucket-name')
92+
client: Storage client instance
93+
94+
Returns:
95+
storage.Bucket: Bucket instance
96+
"""
97+
if _USE_FROM_URI:
98+
return storage.Bucket.from_uri(uri, client=client)
99+
else:
100+
return storage.Bucket.from_string(uri, client=client)
101+
102+
38103
def upload_to_gcs(
39104
source_path: str,
40105
destination_uri: str,
@@ -79,18 +144,18 @@ def upload_to_gcs(
79144
destination_file_uri = (
80145
destination_uri.rstrip("/") + "/" + source_file_relative_posix_path
81146
)
82-
_logger.debug(f'Uploading "{source_file_path}" to "{destination_file_uri}"')
83-
destination_blob = storage.Blob.from_string(
147+
_logger.debug(
148+
'Uploading "%s" to "%s"', source_file_path, destination_file_uri
149+
)
150+
destination_blob = blob_from_uri(
84151
destination_file_uri, client=storage_client
85152
)
86153
destination_blob.upload_from_filename(filename=source_file_path)
87154
else:
88155
source_file_path = source_path
89156
destination_file_uri = destination_uri
90-
_logger.debug(f'Uploading "{source_file_path}" to "{destination_file_uri}"')
91-
destination_blob = storage.Blob.from_string(
92-
destination_file_uri, client=storage_client
93-
)
157+
_logger.debug('Uploading "%s" to "%s"', source_file_path, destination_file_uri)
158+
destination_blob = blob_from_uri(destination_file_uri, client=storage_client)
94159
destination_blob.upload_from_filename(filename=source_file_path)
95160

96161

@@ -234,7 +299,7 @@ def create_gcs_bucket_for_pipeline_artifacts_if_it_does_not_exist(
234299
credentials=credentials,
235300
)
236301

237-
pipelines_bucket = storage.Bucket.from_string(
302+
pipelines_bucket = bucket_from_uri(
238303
uri=output_artifacts_gcs_dir,
239304
client=storage_client,
240305
)
@@ -294,9 +359,9 @@ def download_file_from_gcs(
294359
credentials = credentials or initializer.global_config.credentials
295360

296361
storage_client = storage.Client(project=project, credentials=credentials)
297-
source_blob = storage.Blob.from_string(source_file_uri, client=storage_client)
362+
source_blob = blob_from_uri(source_file_uri, client=storage_client)
298363

299-
_logger.debug(f'Downloading "{source_file_uri}" to "{destination_file_path}"')
364+
_logger.debug('Downloading "%s" to "%s"', source_file_uri, destination_file_path)
300365

301366
source_blob.download_to_filename(filename=destination_file_path)
302367

@@ -354,13 +419,10 @@ def _upload_pandas_df_to_gcs(
354419
"""Uploads the provided Pandas DataFrame to a GCS bucket.
355420
356421
Args:
357-
df (pandas.DataFrame):
358-
Required. The Pandas DataFrame to upload.
359-
upload_gcs_path (str):
360-
Required. The GCS path to upload the data file.
361-
file_format (str):
362-
Required. The format to export the DataFrame to. Currently
363-
only JSONL is supported.
422+
df (pandas.DataFrame): Required. The Pandas DataFrame to upload.
423+
upload_gcs_path (str): Required. The GCS path to upload the data file.
424+
file_format (str): Required. The format to export the DataFrame to.
425+
Currently only JSONL is supported.
364426
365427
Raises:
366428
ValueError: When a file format other than JSONL is provided.
@@ -378,9 +440,9 @@ def _upload_pandas_df_to_gcs(
378440
project=initializer.global_config.project,
379441
credentials=initializer.global_config.credentials,
380442
)
381-
storage.Blob.from_string(
382-
uri=upload_gcs_path, client=storage_client
383-
).upload_from_filename(filename=local_dataset_path)
443+
blob_from_uri(uri=upload_gcs_path, client=storage_client).upload_from_filename(
444+
filename=local_dataset_path
445+
)
384446

385447

386448
def validate_gcs_path(gcs_path: str) -> None:

google/cloud/aiplatform/utils/yaml_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from google.auth import transport
2323
from google.cloud import storage
2424
from google.cloud.aiplatform.constants import pipeline as pipeline_constants
25+
from google.cloud.aiplatform.utils.gcs_utils import blob_from_uri
2526

2627
# Pattern for an Artifact Registry URL.
2728
_VALID_AR_URL = pipeline_constants._VALID_AR_URL
@@ -98,7 +99,7 @@ def _load_yaml_from_gs_uri(
9899
"""
99100
yaml = _maybe_import_yaml()
100101
storage_client = storage.Client(project=project, credentials=credentials)
101-
blob = storage.Blob.from_string(uri, storage_client)
102+
blob = blob_from_uri(uri, storage_client)
102103
return yaml.safe_load(blob.download_as_bytes())
103104

104105

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@
307307
"proto-plus >= 1.22.3, <2.0.0",
308308
"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",
309309
"packaging >= 14.3",
310-
"google-cloud-storage >= 1.32.0, < 3.0.0; python_version<'3.13'",
311-
"google-cloud-storage >= 2.10.0, < 3.0.0; python_version>='3.13'",
310+
"google-cloud-storage >= 1.32.0, < 4.0.0; python_version<'3.13'",
311+
"google-cloud-storage >= 2.10.0, < 4.0.0; python_version>='3.13'",
312312
"google-cloud-bigquery >= 1.15.0, < 4.0.0, !=3.20.0",
313313
"google-cloud-resource-manager >= 1.3.3, < 3.0.0",
314314
"shapely < 3.0.0",

testing/constraints-3.10.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ google-auth==2.35.0 # Tests google-auth with rest async support
66
proto-plus==1.22.3
77
protobuf
88
mock==4.0.2
9-
google-cloud-storage==2.2.1 # Increased for kfp 2.0 compatibility
9+
google-cloud-storage==3.0.0 # Updated to v3.x, backward compatible with v2.x via wrapper
1010
packaging==24.1 # Increased to unbreak canonicalize_version error (b/377774673)
1111
grpcio-testing==1.34.0
1212
mlflow==2.16.0 # Pinned to speed up installation

testing/constraints-3.11.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ google-auth==2.35.0 # Tests google-auth with rest async support
66
proto-plus
77
protobuf
88
mock==4.0.2
9-
google-cloud-storage==2.2.1 # Increased for kfp 2.0 compatibility
9+
google-cloud-storage==3.0.0 # Updated to v3.x, backward compatible with v2.x via wrapper
1010
packaging==24.1 # Increased to unbreak canonicalize_version error (b/377774673)
1111
pytest-xdist==3.3.1 # Pinned to unbreak unit tests
1212
ray==2.5.0 # Pinned until 2.9.3 is verified for Ray tests

testing/constraints-3.12.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ google-api-core==2.21.0 # Tests google-api-core with rest async support
55
google-auth==2.35.0 # Tests google-auth with rest async support
66
proto-plus
77
mock==4.0.2
8-
google-cloud-storage==2.2.1 # Increased for kfp 2.0 compatibility
8+
google-cloud-storage==3.0.0 # Updated to v3.x, backward compatible with v2.x via wrapper
99
packaging==24.1 # Increased to unbreak canonicalize_version error (b/377774673)
1010
pytest-xdist==3.3.1 # Pinned to unbreak unit tests
1111
ray==2.5.0 # Pinned until 2.9.3 is verified for Ray tests

testing/constraints-3.13.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ google-api-core==2.21.0 # Tests google-api-core with rest async support
55
google-auth==2.35.0 # Tests google-auth with rest async support
66
proto-plus
77
mock==4.0.2
8-
google-cloud-storage==2.10.0 # Increased for kfp 2.0 compatibility
8+
google-cloud-storage==3.0.0 # Updated to v3.x, backward compatible with v2.x via wrapper
99
packaging==24.1 # Increased to unbreak canonicalize_version error (b/377774673)
1010
pytest-xdist==3.3.1 # Pinned to unbreak unit tests
1111
ray==2.5.0 # Pinned until 2.9.3 is verified for Ray tests

testing/constraints-3.8.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ google-auth==2.14.1 # Tests google-auth without rest async support
77
proto-plus==1.22.3
88
protobuf
99
mock==4.0.2
10-
google-cloud-storage==2.2.1 # Increased for kfp 2.0 compatibility
10+
google-cloud-storage==3.0.0 # Updated to v3.x, backward compatible with v2.x via wrapper
1111
packaging==24.1 # Increased to unbreak canonicalize_version error (b/377774673)
1212
grpcio-testing==1.34.0
1313
pytest-xdist==3.3.1 # Pinned to unbreak unit tests

testing/constraints-3.9.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ google-auth==2.35.0 # Tests google-auth with rest async support
66
proto-plus==1.22.3
77
protobuf
88
mock==4.0.2
9-
google-cloud-storage==2.2.1 # Increased for kfp 2.0 compatibility
9+
google-cloud-storage==3.0.0 # Updated to v3.x, backward compatible with v2.x via wrapper
1010
packaging==24.1 # Increased to unbreak canonicalize_version error (b/377774673)
1111
grpcio-testing==1.34.0
1212
pytest-xdist==3.3.1 # Pinned to unbreak unit tests

testing/constraints-ray-2.33.0.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ google-api-core
44
proto-plus==1.22.3
55
protobuf
66
mock==4.0.2
7-
google-cloud-storage==2.2.1 # Increased for kfp 2.0 compatibility
7+
google-cloud-storage==3.0.0 # Updated to v3.x, backward compatible with v2.x via wrapper
88
packaging==24.1 # Increased to unbreak canonicalize_version error (b/377774673)
99
grpcio-testing==1.34.0
1010
mlflow==1.30.1 # Pinned to speed up installation

0 commit comments

Comments
 (0)