Skip to content

Commit 2eb3af0

Browse files
tseavercrwilcox
authored andcommitted
feat(storage): add 'ARCHIVE' storage class (#9533)
* feat(storage): add 'ARCHIVE' storage class Closes #9532.
1 parent 2a989a4 commit 2eb3af0

File tree

5 files changed

+75
-15
lines changed

5 files changed

+75
-15
lines changed

packages/google-cloud-storage/google/cloud/storage/blob.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,12 @@
6161
from google.cloud.storage._signing import generate_signed_url_v4
6262
from google.cloud.storage.acl import ACL
6363
from google.cloud.storage.acl import ObjectACL
64-
from google.cloud.storage.constants import STANDARD_STORAGE_CLASS
65-
from google.cloud.storage.constants import NEARLINE_STORAGE_CLASS
64+
from google.cloud.storage.constants import ARCHIVE_STORAGE_CLASS
6665
from google.cloud.storage.constants import COLDLINE_STORAGE_CLASS
6766
from google.cloud.storage.constants import MULTI_REGIONAL_LEGACY_STORAGE_CLASS
67+
from google.cloud.storage.constants import NEARLINE_STORAGE_CLASS
6868
from google.cloud.storage.constants import REGIONAL_LEGACY_STORAGE_CLASS
69+
from google.cloud.storage.constants import STANDARD_STORAGE_CLASS
6970

7071
_STORAGE_HOST = _get_storage_host()
7172

@@ -145,6 +146,7 @@ class Blob(_PropertyMixin):
145146
STANDARD_STORAGE_CLASS,
146147
NEARLINE_STORAGE_CLASS,
147148
COLDLINE_STORAGE_CLASS,
149+
ARCHIVE_STORAGE_CLASS,
148150
MULTI_REGIONAL_LEGACY_STORAGE_CLASS,
149151
REGIONAL_LEGACY_STORAGE_CLASS,
150152
)
@@ -1711,6 +1713,7 @@ def update_storage_class(self, new_class, client=None):
17111713
new storage class for the object. One of:
17121714
:attr:`~google.cloud.storage.constants.NEARLINE_STORAGE_CLASS`,
17131715
:attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`,
1716+
:attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`,
17141717
:attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`,
17151718
:attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`,
17161719
or
@@ -2007,6 +2010,7 @@ def kms_key_name(self):
20072010
:attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`,
20082011
:attr:`~google.cloud.storage.constants.NEARLINE_STORAGE_CLASS`,
20092012
:attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`,
2013+
:attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`,
20102014
:attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`,
20112015
:attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`,
20122016
:attr:`~google.cloud.storage.constants.DURABLE_REDUCED_AVAILABILITY_STORAGE_CLASS`,

packages/google-cloud-storage/google/cloud/storage/bucket.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from google.cloud.storage.acl import BucketACL
4040
from google.cloud.storage.acl import DefaultObjectACL
4141
from google.cloud.storage.blob import Blob
42+
from google.cloud.storage.constants import ARCHIVE_STORAGE_CLASS
4243
from google.cloud.storage.constants import COLDLINE_STORAGE_CLASS
4344
from google.cloud.storage.constants import DUAL_REGION_LOCATION_TYPE
4445
from google.cloud.storage.constants import (
@@ -480,6 +481,7 @@ class Bucket(_PropertyMixin):
480481
STANDARD_STORAGE_CLASS,
481482
NEARLINE_STORAGE_CLASS,
482483
COLDLINE_STORAGE_CLASS,
484+
ARCHIVE_STORAGE_CLASS,
483485
MULTI_REGIONAL_LEGACY_STORAGE_CLASS, # legacy
484486
REGIONAL_LEGACY_STORAGE_CLASS, # legacy
485487
DURABLE_REDUCED_AVAILABILITY_LEGACY_STORAGE_CLASS, # legacy
@@ -1713,6 +1715,7 @@ def storage_class(self):
17131715
If set, one of
17141716
:attr:`~google.cloud.storage.constants.NEARLINE_STORAGE_CLASS`,
17151717
:attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`,
1718+
:attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`,
17161719
:attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`,
17171720
:attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`,
17181721
:attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`,
@@ -1733,6 +1736,7 @@ def storage_class(self, value):
17331736
One of
17341737
:attr:`~google.cloud.storage.constants.NEARLINE_STORAGE_CLASS`,
17351738
:attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`,
1739+
:attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`,
17361740
:attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`,
17371741
:attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`,
17381742
:attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`,

packages/google-cloud-storage/google/cloud/storage/constants.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,28 @@
1616
# Storage classes
1717

1818
STANDARD_STORAGE_CLASS = "STANDARD"
19-
"""Storage class for objects accessed more than once per month."""
19+
"""Storage class for objects accessed more than once per month.
20+
21+
See: https://cloud.google.com/storage/docs/storage-classes
22+
"""
2023

2124
NEARLINE_STORAGE_CLASS = "NEARLINE"
22-
"""Storage class for objects accessed at most once per month."""
25+
"""Storage class for objects accessed at most once per month.
26+
27+
See: https://cloud.google.com/storage/docs/storage-classes
28+
"""
2329

2430
COLDLINE_STORAGE_CLASS = "COLDLINE"
25-
"""Storage class for objects accessed at most once per year."""
31+
"""Storage class for objects accessed at most once per year.
32+
33+
See: https://cloud.google.com/storage/docs/storage-classes
34+
"""
35+
36+
ARCHIVE_STORAGE_CLASS = "ARCHIVE"
37+
"""Storage class for objects accessed less frequently than once per year.
38+
39+
See: https://cloud.google.com/storage/docs/storage-classes
40+
"""
2641

2742
MULTI_REGIONAL_LEGACY_STORAGE_CLASS = "MULTI_REGIONAL"
2843
"""Legacy storage class.
@@ -32,6 +47,8 @@
3247
Can only be used for objects in buckets whose
3348
:attr:`~google.cloud.storage.bucket.Bucket.location_type` is
3449
:attr:`~google.cloud.storage.bucket.Bucket.MULTI_REGION_LOCATION_TYPE`.
50+
51+
See: https://cloud.google.com/storage/docs/storage-classes
3552
"""
3653

3754
REGIONAL_LEGACY_STORAGE_CLASS = "REGIONAL"
@@ -42,6 +59,8 @@
4259
Can only be used for objects in buckets whose
4360
:attr:`~google.cloud.storage.bucket.Bucket.location_type` is
4461
:attr:`~google.cloud.storage.bucket.Bucket.REGION_LOCATION_TYPE`.
62+
63+
See: https://cloud.google.com/storage/docs/storage-classes
4564
"""
4665

4766
DURABLE_REDUCED_AVAILABILITY_LEGACY_STORAGE_CLASS = "DURABLE_REDUCED_AVAILABILITY"

packages/google-cloud-storage/tests/system.py

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,21 +174,41 @@ def test_create_bucket(self):
174174
self.case_buckets_to_delete.append(new_bucket_name)
175175
self.assertEqual(created.name, new_bucket_name)
176176

177+
def test_bucket_create_w_alt_storage_class(self):
178+
from google.cloud.storage import constants
179+
180+
new_bucket_name = "bucket-w-archive" + unique_resource_id("-")
181+
self.assertRaises(
182+
exceptions.NotFound, Config.CLIENT.get_bucket, new_bucket_name
183+
)
184+
bucket = Config.CLIENT.bucket(new_bucket_name)
185+
bucket.storage_class = constants.ARCHIVE_STORAGE_CLASS
186+
retry_429_503(bucket.create)()
187+
self.case_buckets_to_delete.append(new_bucket_name)
188+
created = Config.CLIENT.get_bucket(new_bucket_name)
189+
self.assertEqual(created.storage_class, constants.ARCHIVE_STORAGE_CLASS)
190+
177191
def test_lifecycle_rules(self):
192+
from google.cloud.storage import constants
193+
178194
new_bucket_name = "w-lifcycle-rules" + unique_resource_id("-")
179195
self.assertRaises(
180196
exceptions.NotFound, Config.CLIENT.get_bucket, new_bucket_name
181197
)
182198
bucket = Config.CLIENT.bucket(new_bucket_name)
183199
bucket.add_lifecycle_delete_rule(age=42)
184200
bucket.add_lifecycle_set_storage_class_rule(
185-
"COLDLINE", is_live=False, matches_storage_class=["NEARLINE"]
201+
constants.COLDLINE_STORAGE_CLASS,
202+
is_live=False,
203+
matches_storage_class=[constants.NEARLINE_STORAGE_CLASS],
186204
)
187205

188206
expected_rules = [
189207
LifecycleRuleDelete(age=42),
190208
LifecycleRuleSetStorageClass(
191-
"COLDLINE", is_live=False, matches_storage_class=["NEARLINE"]
209+
constants.COLDLINE_STORAGE_CLASS,
210+
is_live=False,
211+
matches_storage_class=[constants.NEARLINE_STORAGE_CLASS],
192212
),
193213
]
194214

@@ -1235,34 +1255,38 @@ def test_rewrite_rotate_with_user_project(self):
12351255

12361256
class TestStorageUpdateStorageClass(TestStorageFiles):
12371257
def test_update_storage_class_small_file(self):
1258+
from google.cloud.storage import constants
1259+
12381260
blob = self.bucket.blob("SmallFile")
12391261

12401262
file_data = self.FILES["simple"]
12411263
blob.upload_from_filename(file_data["path"])
12421264
self.case_blobs_to_delete.append(blob)
12431265

1244-
blob.update_storage_class("NEARLINE")
1266+
blob.update_storage_class(constants.NEARLINE_STORAGE_CLASS)
12451267
blob.reload()
1246-
self.assertEqual(blob.storage_class, "NEARLINE")
1268+
self.assertEqual(blob.storage_class, constants.NEARLINE_STORAGE_CLASS)
12471269

1248-
blob.update_storage_class("COLDLINE")
1270+
blob.update_storage_class(constants.COLDLINE_STORAGE_CLASS)
12491271
blob.reload()
1250-
self.assertEqual(blob.storage_class, "COLDLINE")
1272+
self.assertEqual(blob.storage_class, constants.COLDLINE_STORAGE_CLASS)
12511273

12521274
def test_update_storage_class_large_file(self):
1275+
from google.cloud.storage import constants
1276+
12531277
blob = self.bucket.blob("BigFile")
12541278

12551279
file_data = self.FILES["big"]
12561280
blob.upload_from_filename(file_data["path"])
12571281
self.case_blobs_to_delete.append(blob)
12581282

1259-
blob.update_storage_class("NEARLINE")
1283+
blob.update_storage_class(constants.NEARLINE_STORAGE_CLASS)
12601284
blob.reload()
1261-
self.assertEqual(blob.storage_class, "NEARLINE")
1285+
self.assertEqual(blob.storage_class, constants.NEARLINE_STORAGE_CLASS)
12621286

1263-
blob.update_storage_class("COLDLINE")
1287+
blob.update_storage_class(constants.COLDLINE_STORAGE_CLASS)
12641288
blob.reload()
1265-
self.assertEqual(blob.storage_class, "COLDLINE")
1289+
self.assertEqual(blob.storage_class, constants.COLDLINE_STORAGE_CLASS)
12661290

12671291

12681292
class TestStorageNotificationCRUD(unittest.TestCase):

packages/google-cloud-storage/tests/unit/test_bucket.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,15 @@ def test_storage_class_setter_COLDLINE(self):
19011901
self.assertEqual(bucket.storage_class, COLDLINE_STORAGE_CLASS)
19021902
self.assertTrue("storageClass" in bucket._changes)
19031903

1904+
def test_storage_class_setter_ARCHIVE(self):
1905+
from google.cloud.storage.constants import ARCHIVE_STORAGE_CLASS
1906+
1907+
NAME = "name"
1908+
bucket = self._make_one(name=NAME)
1909+
bucket.storage_class = ARCHIVE_STORAGE_CLASS
1910+
self.assertEqual(bucket.storage_class, ARCHIVE_STORAGE_CLASS)
1911+
self.assertTrue("storageClass" in bucket._changes)
1912+
19041913
def test_storage_class_setter_MULTI_REGIONAL(self):
19051914
from google.cloud.storage.constants import MULTI_REGIONAL_LEGACY_STORAGE_CLASS
19061915

0 commit comments

Comments
 (0)