Skip to content

Commit 630cbcf

Browse files
committed
feat(storage): add object contexts samples
Add samples for setting, getting, listing (filter) and deleting GCS object contexts. Region tags: storage_set_object_contexts, storage_get_object_contexts, storage_list_object_contexts, storage_delete_object_contexts. Internal bug: b/482946642 [Generated-by: AI]
1 parent 83a4a2b commit 630cbcf

5 files changed

Lines changed: 258 additions & 0 deletions

File tree

‎storage/samples/snippets/snippets_test.py‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import storage_define_bucket_website_configuration
4545
import storage_delete_file
4646
import storage_delete_file_archived_generation
47+
import storage_delete_object_contexts
4748
import storage_disable_bucket_lifecycle_management
4849
import storage_disable_soft_delete
4950
import storage_disable_versioning
@@ -62,13 +63,15 @@
6263
import storage_get_bucket_labels
6364
import storage_get_bucket_metadata
6465
import storage_get_metadata
66+
import storage_get_object_contexts
6567
import storage_get_service_account
6668
import storage_get_soft_delete_policy
6769
import storage_get_soft_deleted_bucket
6870
import storage_list_buckets
6971
import storage_list_file_archived_generations
7072
import storage_list_files
7173
import storage_list_files_with_prefix
74+
import storage_list_object_contexts
7275
import storage_list_soft_deleted_buckets
7376
import storage_list_soft_deleted_object_versions
7477
import storage_list_soft_deleted_objects
@@ -85,6 +88,7 @@
8588
import storage_set_bucket_default_kms_key
8689
import storage_set_client_endpoint
8790
import storage_set_metadata
91+
import storage_set_object_contexts
8892
import storage_set_object_retention_policy
8993
import storage_set_soft_delete_policy
9094
import storage_trace_quickstart
@@ -248,6 +252,58 @@ def test_list_blobs(test_blob, capsys):
248252
assert test_blob.name in out
249253

250254

255+
def test_set_object_contexts(test_blob, capsys):
256+
storage_set_object_contexts.set_object_contexts(
257+
test_blob.bucket.name, test_blob.name
258+
)
259+
out, _ = capsys.readouterr()
260+
assert "key1 = newValue1" in out
261+
assert "key3 = value3" in out
262+
test_blob.reload()
263+
assert "key2" not in test_blob.contexts.custom
264+
265+
266+
def test_get_object_contexts(test_blob, capsys):
267+
storage_get_object_contexts.get_object_contexts(
268+
test_blob.bucket.name, test_blob.name
269+
)
270+
out, _ = capsys.readouterr()
271+
assert f"No contexts found for {test_blob.name}" in out
272+
273+
storage_set_object_contexts.set_object_contexts(
274+
test_blob.bucket.name, test_blob.name
275+
)
276+
storage_get_object_contexts.get_object_contexts(
277+
test_blob.bucket.name, test_blob.name
278+
)
279+
out, _ = capsys.readouterr()
280+
assert "key1 = newValue1" in out
281+
282+
283+
def test_list_object_contexts(test_blob, capsys):
284+
storage_set_object_contexts.set_object_contexts(
285+
test_blob.bucket.name, test_blob.name
286+
)
287+
storage_list_object_contexts.list_object_contexts(
288+
test_blob.bucket.name, 'contexts."key1"="newValue1"'
289+
)
290+
out, _ = capsys.readouterr()
291+
assert test_blob.name in out
292+
293+
294+
def test_delete_object_contexts(test_blob, capsys):
295+
storage_set_object_contexts.set_object_contexts(
296+
test_blob.bucket.name, test_blob.name
297+
)
298+
storage_delete_object_contexts.delete_object_contexts(
299+
test_blob.bucket.name, test_blob.name
300+
)
301+
out, _ = capsys.readouterr()
302+
assert f"Deleted all contexts for {test_blob.name}" in out
303+
test_blob.reload()
304+
assert not (test_blob.contexts and test_blob.contexts.custom)
305+
306+
251307
def test_bucket_metadata(test_bucket, capsys):
252308
storage_get_bucket_metadata.bucket_metadata(test_bucket.name)
253309
out, _ = capsys.readouterr()
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2026 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+
import sys
18+
19+
# [START storage_delete_object_contexts]
20+
from google.cloud import storage
21+
22+
23+
def delete_object_contexts(bucket_name, blob_name):
24+
"""Deletes all custom contexts from an object."""
25+
# The ID of your GCS bucket
26+
# bucket_name = "your-bucket-name"
27+
28+
# The ID of your GCS object
29+
# blob_name = "your-object-name"
30+
31+
storage_client = storage.Client()
32+
bucket = storage_client.bucket(bucket_name)
33+
blob = bucket.get_blob(blob_name)
34+
35+
# Optional: set a metageneration-match precondition to avoid potential race
36+
# conditions and data corruptions. The request to patch is aborted if the
37+
# object's metageneration does not match your precondition.
38+
metageneration_match_precondition = blob.metageneration
39+
40+
blob.contexts = None
41+
blob.patch(if_metageneration_match=metageneration_match_precondition)
42+
43+
print(f"Deleted all contexts for {blob.name}")
44+
45+
46+
# [END storage_delete_object_contexts]
47+
48+
if __name__ == "__main__":
49+
delete_object_contexts(bucket_name=sys.argv[1], blob_name=sys.argv[2])
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 2026 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+
import sys
18+
19+
# [START storage_get_object_contexts]
20+
from google.cloud import storage
21+
22+
23+
def get_object_contexts(bucket_name, blob_name):
24+
"""Prints the custom contexts of an object."""
25+
# The ID of your GCS bucket
26+
# bucket_name = "your-bucket-name"
27+
28+
# The ID of your GCS object
29+
# blob_name = "your-object-name"
30+
31+
storage_client = storage.Client()
32+
bucket = storage_client.bucket(bucket_name)
33+
blob = bucket.get_blob(blob_name)
34+
35+
custom_contexts = blob.contexts.custom if blob.contexts else {}
36+
if not custom_contexts:
37+
print(f"No contexts found for {blob.name}")
38+
return
39+
40+
print(f"Contexts for {blob.name}:")
41+
for key, payload in custom_contexts.items():
42+
print(f"{key} = {payload.value}")
43+
44+
45+
# [END storage_get_object_contexts]
46+
47+
if __name__ == "__main__":
48+
get_object_contexts(bucket_name=sys.argv[1], blob_name=sys.argv[2])
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2026 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+
import sys
18+
19+
# [START storage_list_object_contexts]
20+
from google.cloud import storage
21+
22+
23+
def list_object_contexts(bucket_name, filter_string):
24+
"""Lists objects in a bucket filtered by object contexts."""
25+
# The ID of your GCS bucket
26+
# bucket_name = "your-bucket-name"
27+
28+
# The filter to apply to the object contexts. Supported forms:
29+
# contexts."KEY"="VALUE" objects with the key set to the value
30+
# contexts."KEY":* objects that have the key
31+
# -contexts."KEY":* objects that don't have the key
32+
# -contexts."KEY"="VALUE" objects without the key set to the value
33+
# filter_string = 'contexts."key1"="value1"'
34+
35+
storage_client = storage.Client()
36+
blobs = storage_client.list_blobs(bucket_name, filter_=filter_string)
37+
38+
print(f"Objects matching filter {filter_string}:")
39+
for blob in blobs:
40+
print(blob.name)
41+
42+
43+
# [END storage_list_object_contexts]
44+
45+
if __name__ == "__main__":
46+
list_object_contexts(bucket_name=sys.argv[1], filter_string=sys.argv[2])
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2026 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+
import sys
18+
19+
# [START storage_set_object_contexts]
20+
from google.cloud import storage
21+
from google.cloud.storage.blob import ObjectCustomContextPayload
22+
23+
24+
def set_object_contexts(bucket_name, blob_name):
25+
"""Sets, updates and deletes custom contexts on an object."""
26+
# The ID of your GCS bucket
27+
# bucket_name = "your-bucket-name"
28+
29+
# The ID of your GCS object
30+
# blob_name = "your-object-name"
31+
32+
storage_client = storage.Client()
33+
bucket = storage_client.bucket(bucket_name)
34+
blob = bucket.get_blob(blob_name)
35+
36+
# Optional: set a metageneration-match precondition to avoid potential race
37+
# conditions and data corruptions. The request to patch is aborted if the
38+
# object's metageneration does not match your precondition.
39+
metageneration_match_precondition = blob.metageneration
40+
41+
contexts = blob.contexts
42+
# Add or update the values of custom contexts.
43+
contexts.custom["key1"] = ObjectCustomContextPayload(value="newValue1")
44+
contexts.custom["key3"] = ObjectCustomContextPayload(value="value3")
45+
# Setting a context's value to None deletes that key from the object.
46+
contexts.custom["key2"] = ObjectCustomContextPayload(value=None)
47+
# Reassign the contexts so the change is tracked for the patch request.
48+
blob.contexts = contexts
49+
blob.patch(if_metageneration_match=metageneration_match_precondition)
50+
51+
print(f"Updated contexts for {blob.name}:")
52+
for key, payload in blob.contexts.custom.items():
53+
print(f"{key} = {payload.value}")
54+
55+
56+
# [END storage_set_object_contexts]
57+
58+
if __name__ == "__main__":
59+
set_object_contexts(bucket_name=sys.argv[1], blob_name=sys.argv[2])

0 commit comments

Comments
 (0)