Skip to content

Commit 5256766

Browse files
committed
Implement #370 for Versioning Indicators Extension
1 parent 11b7d75 commit 5256766

File tree

4 files changed

+152
-2
lines changed

4 files changed

+152
-2
lines changed

pystac/extensions/version.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ def successor(self, item_or_collection: Optional[T]) -> None:
195195
def get_schema_uri(cls) -> str:
196196
return SCHEMA_URI
197197

198-
@staticmethod
199-
def ext(obj: T) -> "VersionExtension[T]":
198+
@classmethod
199+
def ext(cls, obj: T) -> "VersionExtension[T]":
200200
"""Extends the given STAC Object with properties from the :stac-ext:`Versioning
201201
Indicators Extension <version>`.
202202
@@ -208,8 +208,10 @@ def ext(obj: T) -> "VersionExtension[T]":
208208
pystac.ExtensionTypeError : If an invalid object type is passed.
209209
"""
210210
if isinstance(obj, pystac.Collection):
211+
cls.validate_has_extension(obj)
211212
return cast(VersionExtension[T], CollectionVersionExtension(obj))
212213
if isinstance(obj, pystac.Item):
214+
cls.validate_has_extension(obj)
213215
return cast(VersionExtension[T], ItemVersionExtension(obj))
214216
else:
215217
raise pystac.ExtensionTypeError(
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"stac_version": "1.0.0-rc.1",
3+
"stac_extensions": [
4+
"https://stac-extensions.github.io/version/v1.0.0/schema.json"
5+
],
6+
"id": "merraclim",
7+
"type": "Collection",
8+
"title": "MERRAclim",
9+
"description": "A high-resolution global dataset of remotely sensed bioclimatic variables for ecological modelling.",
10+
"license": "CC0-1.0",
11+
"version": "1",
12+
"deprecated": true,
13+
"extent": {
14+
"spatial": {
15+
"bbox": [
16+
[
17+
-180,
18+
-90,
19+
180,
20+
90
21+
]
22+
]
23+
},
24+
"temporal": {
25+
"interval": [
26+
[
27+
"1980-01-01T00:00:00Z",
28+
"2009-12-31T23:59:59Z"
29+
]
30+
]
31+
}
32+
},
33+
"links": [
34+
{
35+
"rel": "self",
36+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/v1/collection.json"
37+
},
38+
{
39+
"rel": "item",
40+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/v1/item.json"
41+
},
42+
{
43+
"rel": "root",
44+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/catalog.json"
45+
},
46+
{
47+
"rel": "latest-version",
48+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/v2/collection.json"
49+
}
50+
]
51+
}

tests/data-files/version/item.json

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"stac_version": "1.0.0-rc.1",
3+
"stac_extensions": [
4+
"https://stac-extensions.github.io/version/v1.0.0/schema.json"
5+
],
6+
"id": "MERRAclim.2_5m_min_80s",
7+
"type": "Feature",
8+
"geometry": {
9+
"type": "Polygon",
10+
"coordinates": [
11+
[
12+
[
13+
-180,
14+
-90
15+
],
16+
[
17+
180,
18+
-90
19+
],
20+
[
21+
180,
22+
90
23+
],
24+
[
25+
-180,
26+
90
27+
],
28+
[
29+
-180,
30+
-90
31+
]
32+
]
33+
]
34+
},
35+
"bbox": [
36+
-180,
37+
-90,
38+
180,
39+
90
40+
],
41+
"properties": {
42+
"version": "1",
43+
"title": "MERRAclim. 2_5m_min_80s",
44+
"description": "MERRAclim Dataset. 19 global bioclimatic variables from the 1980s decade at 2.5 arcminutes resolution in GEOtiff format. The humidity version used is the min. The variables have been built using the same protocol as WorldClim with data from MERRA. Temperature layers (BIO1-BIO11) are in degree Celsius multiplied by 10, humidity layers (BIO12-BIO19) are in kg of water/kg of air multiplied by 100000.",
45+
"datetime": "1985-07-01T00:00:00Z"
46+
},
47+
"collection": "merraclim",
48+
"links": [
49+
{
50+
"rel": "self",
51+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/v1/item.json"
52+
},
53+
{
54+
"rel": "collection",
55+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/v1/collection.json"
56+
},
57+
{
58+
"rel": "parent",
59+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/v1/collection.json"
60+
},
61+
{
62+
"rel": "root",
63+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/catalog.json"
64+
},
65+
{
66+
"rel": "latest-version",
67+
"href": "https://datadryad.org/resource/doi:10.5061/dryad.s2v81/v2/item.json"
68+
}
69+
],
70+
"assets": {
71+
"primary": {
72+
"href": "https://datadryad.org/stash/downloads/file_stream/100467",
73+
"type": "application/zip",
74+
"title": "MERRAclim. 2_5m_min_80s"
75+
}
76+
}
77+
}

tests/extensions/test_version.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class ItemVersionExtensionTest(unittest.TestCase):
3333
def setUp(self) -> None:
3434
super().setUp()
3535
self.item = make_item(2011)
36+
self.example_item_uri = TestCases.get_path("data-files/version/item.json")
3637

3738
def test_rel_types(self) -> None:
3839
self.assertEqual(str(VersionRelType.LATEST), "latest-version")
@@ -218,6 +219,14 @@ def test_multiple_link_setting(self) -> None:
218219
self.assertEqual(1, len(links))
219220
self.assertEqual(expected_href, links[0].get_href())
220221

222+
def test_extension_not_implemented(self) -> None:
223+
# Should raise exception if Item does not include extension URI
224+
item = pystac.Item.from_file(self.example_item_uri)
225+
item.stac_extensions.remove(VersionExtension.get_schema_uri())
226+
227+
with self.assertRaises(pystac.ExtensionNotImplemented):
228+
_ = VersionExtension.ext(item)
229+
221230

222231
def make_collection(year: int) -> pystac.Collection:
223232
asset_id = f"my/collection/of/things/{year}"
@@ -243,6 +252,9 @@ class CollectionVersionExtensionTest(unittest.TestCase):
243252
def setUp(self) -> None:
244253
super().setUp()
245254
self.collection = make_collection(2011)
255+
self.example_collection_uri = TestCases.get_path(
256+
"data-files/version/collection.json"
257+
)
246258

247259
def test_stac_extensions(self) -> None:
248260
self.assertTrue(VersionExtension.has_extension(self.collection))
@@ -423,6 +435,14 @@ def test_multiple_link_setting(self) -> None:
423435
self.assertEqual(1, len(links))
424436
self.assertEqual(expected_href, links[0].get_href())
425437

438+
def test_extension_not_implemented(self) -> None:
439+
# Should raise exception if Collection does not include extension URI
440+
collection = pystac.Collection.from_file(self.example_collection_uri)
441+
collection.stac_extensions.remove(VersionExtension.get_schema_uri())
442+
443+
with self.assertRaises(pystac.ExtensionNotImplemented):
444+
_ = VersionExtension.ext(collection)
445+
426446

427447
if __name__ == "__main__":
428448
unittest.main()

0 commit comments

Comments
 (0)