From d2d60df13dd5caea8acac6b68ee717b9c38593bd Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 07:18:05 +0000 Subject: [PATCH 1/2] feat(storagecontrol): add anywhere cache samples for python Co-authored-by: nidhiii-27 <224584462+nidhiii-27@users.noreply.github.com> --- storagecontrol/anywhere_cache_create.py | 53 +++++++++++++++++ storagecontrol/anywhere_cache_disable.py | 41 ++++++++++++++ storagecontrol/anywhere_cache_get.py | 41 ++++++++++++++ storagecontrol/anywhere_cache_list.py | 44 +++++++++++++++ storagecontrol/anywhere_cache_pause.py | 40 +++++++++++++ storagecontrol/anywhere_cache_resume.py | 40 +++++++++++++ storagecontrol/anywhere_cache_test.py | 72 ++++++++++++++++++++++++ storagecontrol/anywhere_cache_update.py | 54 ++++++++++++++++++ storagecontrol/managed_folder_list.py | 2 + storagecontrol/snippets_test.py | 1 - 10 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 storagecontrol/anywhere_cache_create.py create mode 100644 storagecontrol/anywhere_cache_disable.py create mode 100644 storagecontrol/anywhere_cache_get.py create mode 100644 storagecontrol/anywhere_cache_list.py create mode 100644 storagecontrol/anywhere_cache_pause.py create mode 100644 storagecontrol/anywhere_cache_resume.py create mode 100644 storagecontrol/anywhere_cache_test.py create mode 100644 storagecontrol/anywhere_cache_update.py diff --git a/storagecontrol/anywhere_cache_create.py b/storagecontrol/anywhere_cache_create.py new file mode 100644 index 00000000000..c0f66d43ff4 --- /dev/null +++ b/storagecontrol/anywhere_cache_create.py @@ -0,0 +1,53 @@ +# Copyright 2026 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 +# +# https://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. + +import sys + +# [START storage_control_create_anywhere_cache] +from google.cloud import storage_control_v2 + + +def create_anywhere_cache(bucket_name: str, zone: str) -> None: + # The ID of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # The zone in which to create the Anywhere Cache + # zone = "us-central1-a" + + storage_control_client = storage_control_v2.StorageControlClient() + # The storage bucket path uses the global access pattern, in which the "_" + # denotes this bucket exists in the global namespace. + project_path = storage_control_client.common_project_path("_") + bucket_path = f"{project_path}/buckets/{bucket_name}" + + request = storage_control_v2.CreateAnywhereCacheRequest( + parent=bucket_path, + anywhere_cache=storage_control_v2.AnywhereCache( + zone=zone, + admission_policy="admit-on-second-miss", + ), + ) + # This operation is long-running. Real-world applications may want to + # use callbacks, coroutines, or polling to handle the response. + operation = storage_control_client.create_anywhere_cache(request=request) + response = operation.result() + + print(f"Created Anywhere Cache: {response.name}") + + +# [END storage_control_create_anywhere_cache] + + +if __name__ == "__main__": + create_anywhere_cache(bucket_name=sys.argv[1], zone=sys.argv[2]) diff --git a/storagecontrol/anywhere_cache_disable.py b/storagecontrol/anywhere_cache_disable.py new file mode 100644 index 00000000000..5096e89e879 --- /dev/null +++ b/storagecontrol/anywhere_cache_disable.py @@ -0,0 +1,41 @@ +# Copyright 2026 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 +# +# https://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. + +import sys + +# [START storage_control_disable_anywhere_cache] +from google.cloud import storage_control_v2 + + +def disable_anywhere_cache(anywhere_cache_id: str) -> None: + # The full name of the Anywhere Cache + # anywhere_cache_id = "projects/_/buckets/bucket-name/anywhereCaches/zone-id" + + storage_control_client = storage_control_v2.StorageControlClient() + + request = storage_control_v2.DisableAnywhereCacheRequest( + name=anywhere_cache_id, + ) + # The DisableAnywhereCache RPC returns google.protobuf.Empty, + # so we cannot access attributes like .name on the response. + storage_control_client.disable_anywhere_cache(request=request) + + print(f"Disabled Anywhere Cache: {anywhere_cache_id}") + + +# [END storage_control_disable_anywhere_cache] + + +if __name__ == "__main__": + disable_anywhere_cache(anywhere_cache_id=sys.argv[1]) diff --git a/storagecontrol/anywhere_cache_get.py b/storagecontrol/anywhere_cache_get.py new file mode 100644 index 00000000000..174cd6bc869 --- /dev/null +++ b/storagecontrol/anywhere_cache_get.py @@ -0,0 +1,41 @@ +# Copyright 2026 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 +# +# https://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. + +import sys + +# [START storage_control_get_anywhere_cache] +from google.cloud import storage_control_v2 + + +def get_anywhere_cache(anywhere_cache_id: str) -> None: + # The full name of the Anywhere Cache + # anywhere_cache_id = "projects/_/buckets/bucket-name/anywhereCaches/zone-id" + + storage_control_client = storage_control_v2.StorageControlClient() + + request = storage_control_v2.GetAnywhereCacheRequest( + name=anywhere_cache_id, + ) + response = storage_control_client.get_anywhere_cache(request=request) + + print(f"Anywhere Cache: {response.name}") + print(f"Admission Policy: {response.admission_policy}") + print(f"State: {response.state}") + + +# [END storage_control_get_anywhere_cache] + + +if __name__ == "__main__": + get_anywhere_cache(anywhere_cache_id=sys.argv[1]) diff --git a/storagecontrol/anywhere_cache_list.py b/storagecontrol/anywhere_cache_list.py new file mode 100644 index 00000000000..46da06c1fb7 --- /dev/null +++ b/storagecontrol/anywhere_cache_list.py @@ -0,0 +1,44 @@ +# Copyright 2026 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 +# +# https://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. + +import sys + +# [START storage_control_list_anywhere_caches] +from google.cloud import storage_control_v2 + + +def list_anywhere_caches(bucket_name: str) -> None: + # The ID of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + storage_control_client = storage_control_v2.StorageControlClient() + # The storage bucket path uses the global access pattern, in which the "_" + # denotes this bucket exists in the global namespace. + project_path = storage_control_client.common_project_path("_") + bucket_path = f"{project_path}/buckets/{bucket_name}" + + request = storage_control_v2.ListAnywhereCachesRequest( + parent=bucket_path, + ) + page_result = storage_control_client.list_anywhere_caches(request=request) + + for response in page_result: + print(f"Anywhere Cache: {response.name}") + + +# [END storage_control_list_anywhere_caches] + + +if __name__ == "__main__": + list_anywhere_caches(bucket_name=sys.argv[1]) diff --git a/storagecontrol/anywhere_cache_pause.py b/storagecontrol/anywhere_cache_pause.py new file mode 100644 index 00000000000..bda22446f36 --- /dev/null +++ b/storagecontrol/anywhere_cache_pause.py @@ -0,0 +1,40 @@ +# Copyright 2026 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 +# +# https://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. + +import sys + +# [START storage_control_pause_anywhere_cache] +from google.cloud import storage_control_v2 + + +def pause_anywhere_cache(anywhere_cache_id: str) -> None: + # The full name of the Anywhere Cache + # anywhere_cache_id = "projects/_/buckets/bucket-name/anywhereCaches/zone-id" + + storage_control_client = storage_control_v2.StorageControlClient() + + request = storage_control_v2.PauseAnywhereCacheRequest( + name=anywhere_cache_id, + ) + response = storage_control_client.pause_anywhere_cache(request=request) + + print(f"Paused Anywhere Cache: {response.name}") + print(f"State: {response.state}") + + +# [END storage_control_pause_anywhere_cache] + + +if __name__ == "__main__": + pause_anywhere_cache(anywhere_cache_id=sys.argv[1]) diff --git a/storagecontrol/anywhere_cache_resume.py b/storagecontrol/anywhere_cache_resume.py new file mode 100644 index 00000000000..d871b42f9e3 --- /dev/null +++ b/storagecontrol/anywhere_cache_resume.py @@ -0,0 +1,40 @@ +# Copyright 2026 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 +# +# https://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. + +import sys + +# [START storage_control_resume_anywhere_cache] +from google.cloud import storage_control_v2 + + +def resume_anywhere_cache(anywhere_cache_id: str) -> None: + # The full name of the Anywhere Cache + # anywhere_cache_id = "projects/_/buckets/bucket-name/anywhereCaches/zone-id" + + storage_control_client = storage_control_v2.StorageControlClient() + + request = storage_control_v2.ResumeAnywhereCacheRequest( + name=anywhere_cache_id, + ) + response = storage_control_client.resume_anywhere_cache(request=request) + + print(f"Resumed Anywhere Cache: {response.name}") + print(f"State: {response.state}") + + +# [END storage_control_resume_anywhere_cache] + + +if __name__ == "__main__": + resume_anywhere_cache(anywhere_cache_id=sys.argv[1]) diff --git a/storagecontrol/anywhere_cache_test.py b/storagecontrol/anywhere_cache_test.py new file mode 100644 index 00000000000..782477e46d3 --- /dev/null +++ b/storagecontrol/anywhere_cache_test.py @@ -0,0 +1,72 @@ +# Copyright 2026 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 +# +# https://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 google.cloud import storage + +import pytest + +import anywhere_cache_create +import anywhere_cache_disable +import anywhere_cache_get +import anywhere_cache_list +import anywhere_cache_pause +import anywhere_cache_resume +import anywhere_cache_update + + +def test_anywhere_cache_lifecycle( + capsys: pytest.LogCaptureFixture, ubla_enabled_bucket: storage.Bucket +) -> None: + bucket_name = ubla_enabled_bucket.name + zone = "us-central1-a" + anywhere_cache_id = f"projects/_/buckets/{bucket_name}/anywhereCaches/{zone}" + + # Test create + anywhere_cache_create.create_anywhere_cache(bucket_name=bucket_name, zone=zone) + out, _ = capsys.readouterr() + assert anywhere_cache_id in out + + # Test get + anywhere_cache_get.get_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + out, _ = capsys.readouterr() + assert anywhere_cache_id in out + assert "admit-on-second-miss" in out + + # Test list + anywhere_cache_list.list_anywhere_caches(bucket_name=bucket_name) + out, _ = capsys.readouterr() + assert anywhere_cache_id in out + + # Test update + anywhere_cache_update.update_anywhere_cache( + anywhere_cache_id=anywhere_cache_id, admission_policy="admit-on-second-miss" + ) + out, _ = capsys.readouterr() + assert anywhere_cache_id in out + assert "admit-on-second-miss" in out + + # Test pause + anywhere_cache_pause.pause_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + out, _ = capsys.readouterr() + assert anywhere_cache_id in out + + # Test resume + anywhere_cache_resume.resume_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + out, _ = capsys.readouterr() + assert anywhere_cache_id in out + + # Test disable + anywhere_cache_disable.disable_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + out, _ = capsys.readouterr() + assert anywhere_cache_id in out diff --git a/storagecontrol/anywhere_cache_update.py b/storagecontrol/anywhere_cache_update.py new file mode 100644 index 00000000000..ca75533e9c1 --- /dev/null +++ b/storagecontrol/anywhere_cache_update.py @@ -0,0 +1,54 @@ +# Copyright 2026 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 +# +# https://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. + +import sys + +# [START storage_control_update_anywhere_cache] +from google.cloud import storage_control_v2 +from google.protobuf import field_mask_pb2 + + +def update_anywhere_cache(anywhere_cache_id: str, admission_policy: str) -> None: + # The full name of the Anywhere Cache + # anywhere_cache_id = "projects/_/buckets/bucket-name/anywhereCaches/zone-id" + + # The new admission policy + # admission_policy = "admit-on-second-miss" + + storage_control_client = storage_control_v2.StorageControlClient() + + anywhere_cache = storage_control_v2.AnywhereCache( + name=anywhere_cache_id, + admission_policy=admission_policy, + ) + update_mask = field_mask_pb2.FieldMask(paths=["admission_policy"]) + + request = storage_control_v2.UpdateAnywhereCacheRequest( + anywhere_cache=anywhere_cache, + update_mask=update_mask, + ) + # This operation is long-running. Real-world applications may want to + # use callbacks, coroutines, or polling to handle the response. + operation = storage_control_client.update_anywhere_cache(request=request) + response = operation.result() + + print(f"Updated Anywhere Cache: {response.name}") + print(f"New Admission Policy: {response.admission_policy}") + + +# [END storage_control_update_anywhere_cache] + + +if __name__ == "__main__": + update_anywhere_cache(anywhere_cache_id=sys.argv[1], admission_policy=sys.argv[2]) diff --git a/storagecontrol/managed_folder_list.py b/storagecontrol/managed_folder_list.py index e2ef9703b23..1a056c2b560 100644 --- a/storagecontrol/managed_folder_list.py +++ b/storagecontrol/managed_folder_list.py @@ -46,6 +46,8 @@ def list_managed_folders(bucket_name: str = "your-bucket-name") -> None: print(f"Managed folders in bucket {bucket_resource_name}:") for managed_folder in managed_folders: print(f"\t{managed_folder.name}") + + # [END storage_control_managed_folder_list] diff --git a/storagecontrol/snippets_test.py b/storagecontrol/snippets_test.py index 218a3b7f26a..ba3dc72f166 100644 --- a/storagecontrol/snippets_test.py +++ b/storagecontrol/snippets_test.py @@ -26,7 +26,6 @@ import managed_folder_list import rename_folder - # === Folders === # From 2cf1327c2cd8132f03ecf2f8b63fae570266bc24 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 08:31:44 +0000 Subject: [PATCH 2/2] feat(storagecontrol): add anywhere cache samples for python Co-authored-by: nidhiii-27 <224584462+nidhiii-27@users.noreply.github.com> --- storagecontrol/anywhere_cache_create.py | 6 ++- storagecontrol/anywhere_cache_list.py | 6 ++- storagecontrol/anywhere_cache_test.py | 72 +++++++++++++++++++++---- 3 files changed, 70 insertions(+), 14 deletions(-) diff --git a/storagecontrol/anywhere_cache_create.py b/storagecontrol/anywhere_cache_create.py index c0f66d43ff4..9b14c35808f 100644 --- a/storagecontrol/anywhere_cache_create.py +++ b/storagecontrol/anywhere_cache_create.py @@ -26,10 +26,12 @@ def create_anywhere_cache(bucket_name: str, zone: str) -> None: # zone = "us-central1-a" storage_control_client = storage_control_v2.StorageControlClient() + # The storage bucket path uses the global access pattern, in which the "_" # denotes this bucket exists in the global namespace. - project_path = storage_control_client.common_project_path("_") - bucket_path = f"{project_path}/buckets/{bucket_name}" + bucket_path = ( + storage_control_client.common_project_path("_") + f"/buckets/{bucket_name}" + ) request = storage_control_v2.CreateAnywhereCacheRequest( parent=bucket_path, diff --git a/storagecontrol/anywhere_cache_list.py b/storagecontrol/anywhere_cache_list.py index 46da06c1fb7..0b0f91eb7fa 100644 --- a/storagecontrol/anywhere_cache_list.py +++ b/storagecontrol/anywhere_cache_list.py @@ -23,10 +23,12 @@ def list_anywhere_caches(bucket_name: str) -> None: # bucket_name = "your-unique-bucket-name" storage_control_client = storage_control_v2.StorageControlClient() + # The storage bucket path uses the global access pattern, in which the "_" # denotes this bucket exists in the global namespace. - project_path = storage_control_client.common_project_path("_") - bucket_path = f"{project_path}/buckets/{bucket_name}" + bucket_path = ( + storage_control_client.common_project_path("_") + f"/buckets/{bucket_name}" + ) request = storage_control_v2.ListAnywhereCachesRequest( parent=bucket_path, diff --git a/storagecontrol/anywhere_cache_test.py b/storagecontrol/anywhere_cache_test.py index 782477e46d3..b09dd46a136 100644 --- a/storagecontrol/anywhere_cache_test.py +++ b/storagecontrol/anywhere_cache_test.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import backoff +from google.api_core import exceptions from google.cloud import storage import pytest @@ -26,47 +28,97 @@ def test_anywhere_cache_lifecycle( - capsys: pytest.LogCaptureFixture, ubla_enabled_bucket: storage.Bucket + capsys: pytest.CaptureFixture, ubla_enabled_bucket: storage.Bucket ) -> None: bucket_name = ubla_enabled_bucket.name zone = "us-central1-a" anywhere_cache_id = f"projects/_/buckets/{bucket_name}/anywhereCaches/{zone}" # Test create - anywhere_cache_create.create_anywhere_cache(bucket_name=bucket_name, zone=zone) + # Creation can be subject to rate limits or transient errors. + @backoff.on_exception(backoff.expo, exceptions.GoogleAPICallError, max_tries=3) + def do_create() -> None: + anywhere_cache_create.create_anywhere_cache(bucket_name=bucket_name, zone=zone) + + do_create() out, _ = capsys.readouterr() assert anywhere_cache_id in out # Test get - anywhere_cache_get.get_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + # Use retry to handle eventual consistency. + @backoff.on_exception( + backoff.expo, (exceptions.NotFound, exceptions.ServiceUnavailable), max_time=120 + ) + def do_get() -> None: + anywhere_cache_get.get_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + + do_get() out, _ = capsys.readouterr() assert anywhere_cache_id in out assert "admit-on-second-miss" in out # Test list - anywhere_cache_list.list_anywhere_caches(bucket_name=bucket_name) + # Use retry to handle eventual consistency. + @backoff.on_exception( + backoff.expo, (exceptions.NotFound, exceptions.ServiceUnavailable), max_time=120 + ) + def do_list() -> None: + anywhere_cache_list.list_anywhere_caches(bucket_name=bucket_name) + + do_list() out, _ = capsys.readouterr() assert anywhere_cache_id in out # Test update - anywhere_cache_update.update_anywhere_cache( - anywhere_cache_id=anywhere_cache_id, admission_policy="admit-on-second-miss" + # Use retry to handle eventual consistency. + @backoff.on_exception( + backoff.expo, (exceptions.NotFound, exceptions.ServiceUnavailable), max_time=120 ) + def do_update() -> None: + # Update to a different policy to verify the change. + anywhere_cache_update.update_anywhere_cache( + anywhere_cache_id=anywhere_cache_id, admission_policy="admit-on-first-miss" + ) + + do_update() out, _ = capsys.readouterr() assert anywhere_cache_id in out - assert "admit-on-second-miss" in out + assert "admit-on-first-miss" in out # Test pause - anywhere_cache_pause.pause_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + # Use retry to handle eventual consistency. + @backoff.on_exception( + backoff.expo, (exceptions.NotFound, exceptions.ServiceUnavailable), max_time=120 + ) + def do_pause() -> None: + anywhere_cache_pause.pause_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + + do_pause() out, _ = capsys.readouterr() assert anywhere_cache_id in out # Test resume - anywhere_cache_resume.resume_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + # Use retry to handle eventual consistency. + @backoff.on_exception( + backoff.expo, (exceptions.NotFound, exceptions.ServiceUnavailable), max_time=120 + ) + def do_resume() -> None: + anywhere_cache_resume.resume_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + + do_resume() out, _ = capsys.readouterr() assert anywhere_cache_id in out # Test disable - anywhere_cache_disable.disable_anywhere_cache(anywhere_cache_id=anywhere_cache_id) + # Use retry to handle eventual consistency. + @backoff.on_exception( + backoff.expo, (exceptions.NotFound, exceptions.ServiceUnavailable), max_time=120 + ) + def do_disable() -> None: + anywhere_cache_disable.disable_anywhere_cache( + anywhere_cache_id=anywhere_cache_id + ) + + do_disable() out, _ = capsys.readouterr() assert anywhere_cache_id in out