Skip to content

Commit 0aa403a

Browse files
authored
samples: Add samples for soft_deleted_buckets (#1463)
* samples: Add samples for soft_deleted_buckets * fix: fix linting errors * fix: fix linting errors on #1455 - attempt2 * fix: fix linting errors on #1455 - attempt3 * fix: test_list_buckets errors * fix: address comments by @JesseLovelace * samples: Add storage_list_soft_deleted_buckets.py sample and test cases for all * fix: lint errors space b/w methods. * fix: lint issues. * fix: undo changes in storage_list_buckets.py * fix: lint errors * Change copyright statement. * fix minor typos in doc strings as per code comment
1 parent 9d0ad4c commit 0aa403a

File tree

4 files changed

+156
-0
lines changed

4 files changed

+156
-0
lines changed

packages/google-cloud-storage/samples/snippets/snippets_test.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,12 @@
5959
import storage_get_autoclass
6060
import storage_get_bucket_labels
6161
import storage_get_bucket_metadata
62+
import storage_get_soft_deleted_bucket
6263
import storage_get_metadata
6364
import storage_get_service_account
6465
import storage_list_buckets
66+
import storage_list_soft_deleted_buckets
67+
import storage_restore_soft_deleted_bucket
6568
import storage_list_file_archived_generations
6669
import storage_list_files
6770
import storage_list_files_with_prefix
@@ -131,6 +134,19 @@ def test_bucket():
131134
bucket.delete(force=True)
132135

133136

137+
@pytest.fixture(scope="module")
138+
def test_soft_deleted_bucket():
139+
"""Yields a soft-deleted bucket."""
140+
bucket = None
141+
while bucket is None or bucket.exists():
142+
bucket_name = f"storage-snippets-test-{uuid.uuid4()}"
143+
bucket = storage.Client().bucket(bucket_name)
144+
bucket.create()
145+
# [Assumption] Bucket is created with default policy , ie soft delete on.
146+
bucket.delete()
147+
yield bucket
148+
149+
134150
@pytest.fixture(scope="function")
135151
def test_public_bucket():
136152
# The new projects don't allow to make a bucket available to public, so
@@ -195,6 +211,12 @@ def test_list_buckets(test_bucket, capsys):
195211
assert test_bucket.name in out
196212

197213

214+
def test_list_soft_deleted_buckets(test_soft_deleted_bucket, capsys):
215+
storage_list_soft_deleted_buckets.list_soft_deleted_buckets()
216+
out, _ = capsys.readouterr()
217+
assert test_soft_deleted_bucket.name in out
218+
219+
198220
def test_list_blobs(test_blob, capsys):
199221
storage_list_files.list_blobs(test_blob.bucket.name)
200222
out, _ = capsys.readouterr()
@@ -207,6 +229,18 @@ def test_bucket_metadata(test_bucket, capsys):
207229
assert test_bucket.name in out
208230

209231

232+
def test_get_soft_deleted_bucket(test_soft_deleted_bucket, capsys):
233+
storage_get_soft_deleted_bucket.get_soft_deleted_bucket(test_soft_deleted_bucket.name, test_soft_deleted_bucket.generation)
234+
out, _ = capsys.readouterr()
235+
assert test_soft_deleted_bucket.name in out
236+
237+
238+
def test_restore_soft_deleted_bucket(test_soft_deleted_bucket, capsys):
239+
storage_restore_soft_deleted_bucket.restore_bucket(test_soft_deleted_bucket.name, test_soft_deleted_bucket.generation)
240+
out, _ = capsys.readouterr()
241+
assert test_soft_deleted_bucket.name in out
242+
243+
210244
def test_list_blobs_with_prefix(test_blob, capsys):
211245
storage_list_files_with_prefix.list_blobs_with_prefix(
212246
test_blob.bucket.name, prefix="storage_snippets"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the 'License');
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
18+
import sys
19+
20+
# [START storage_get_soft_deleted_bucket]
21+
22+
from google.cloud import storage
23+
24+
25+
def get_soft_deleted_bucket(bucket_name, generation):
26+
"""Prints out a soft-deleted bucket's metadata.
27+
28+
Args:
29+
bucket_name: str
30+
The name of the bucket to get.
31+
32+
generation:
33+
The generation of the bucket.
34+
35+
"""
36+
storage_client = storage.Client()
37+
bucket = storage_client.get_bucket(bucket_name, soft_deleted=True, generation=generation)
38+
39+
print(f"ID: {bucket.id}")
40+
print(f"Name: {bucket.name}")
41+
print(f"Soft Delete time: {bucket.soft_delete_time}")
42+
print(f"Hard Delete Time : {bucket.hard_delete_time}")
43+
44+
45+
# [END storage_get_soft_deleted_bucket]
46+
47+
if __name__ == "__main__":
48+
get_soft_deleted_bucket(bucket_name=sys.argv[1], generation=sys.argv[2])
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the 'License');
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# [START storage_list_soft_deleted_buckets]
18+
19+
from google.cloud import storage
20+
21+
22+
def list_soft_deleted_buckets():
23+
"""Lists all soft-deleted buckets."""
24+
25+
storage_client = storage.Client()
26+
buckets = storage_client.list_buckets(soft_deleted=True)
27+
28+
for bucket in buckets:
29+
print(bucket.name)
30+
31+
32+
# [END storage_list_soft_deleted_buckets]
33+
34+
35+
if __name__ == "__main__":
36+
list_soft_deleted_buckets()
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the 'License');
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
18+
import sys
19+
20+
# [START storage_restore_soft_deleted_bucket]
21+
22+
from google.cloud import storage
23+
24+
25+
def restore_bucket(bucket_name, bucket_generation):
26+
storage_client = storage.Client()
27+
bucket = storage_client.restore_bucket(bucket_name=bucket_name, generation=bucket_generation)
28+
print(f"Soft-deleted bucket {bucket.name} with ID: {bucket.id} was restored.")
29+
print(f"Bucket Generation: {bucket.generation}")
30+
31+
32+
# [END storage_restore_soft_deleted_bucket]
33+
34+
if __name__ == "__main__":
35+
if len(sys.argv) != 3:
36+
print("Wrong inputs!! Usage of script - \"python storage_restore_soft_deleted_bucket.py <bucket_name> <bucket_generation>\" ")
37+
sys.exit(1)
38+
restore_bucket(bucket_name=sys.argv[1], bucket_generation=sys.argv[2])

0 commit comments

Comments
 (0)