Skip to content

Commit 37282b3

Browse files
committed
--wip-- [skip ci]
1 parent e456289 commit 37282b3

24 files changed

+954
-1218
lines changed

pystac/extensions/ext.py

+4
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,10 @@ def table(self) -> TableExtension[T]:
267267
def view(self) -> ViewExtension[T]:
268268
return ViewExtension.ext(self.stac_object)
269269

270+
@property
271+
def version(self) -> VersionExtension[T]:
272+
return VersionExtension.ext(self.stac_object)
273+
270274

271275
@dataclass
272276
class AssetExt(_AssetExt[pystac.Asset]):

pystac/extensions/version.py

+41-7
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
from pystac.errors import DeprecatedWarning
1818
from pystac.extensions.base import ExtensionManagementMixin, PropertiesExtension
1919
from pystac.extensions.hooks import ExtensionHooks
20-
from pystac.utils import StringEnum, get_required, map_opt
20+
from pystac.utils import StringEnum, map_opt
2121

22-
T = TypeVar("T", pystac.Collection, pystac.Item)
22+
T = TypeVar("T", pystac.Collection, pystac.Item, pystac.Asset)
2323

24-
SCHEMA_URI = "https://stac-extensions.github.io/version/v1.0.0/schema.json"
24+
SCHEMA_URI = "https://stac-extensions.github.io/version/v1.2.0/schema.json"
2525

2626
# STAC fields - These are unusual for an extension in that they do not have
2727
# a prefix. e.g. nothing like "ver:"
@@ -106,14 +106,14 @@ def apply(
106106
self.successor = successor
107107

108108
@property
109-
def version(self) -> str:
109+
def version(self) -> str | None:
110110
"""Get or sets a version string of the :class:`~pystac.Item` or
111111
:class:`pystac.Collection`."""
112-
return get_required(self._get_property(VERSION, str), self, VERSION)
112+
return self._get_property(VERSION, str)
113113

114114
@version.setter
115115
def version(self, v: str) -> None:
116-
self._set_property(VERSION, v, pop_if_none=False)
116+
self._set_property(VERSION, v, pop_if_none=True)
117117

118118
@property
119119
def deprecated(self) -> bool | None:
@@ -205,6 +205,14 @@ def successor(self, item_or_collection: T | None) -> None:
205205
)
206206
)
207207

208+
@property
209+
def experimental(self) -> bool | None:
210+
return self._get_property("experimental", bool)
211+
212+
@experimental.setter
213+
def experimental(self, experimental: bool) -> None:
214+
self._set_property("experimental", experimental, pop_if_none=True)
215+
208216
@classmethod
209217
def get_schema_uri(cls) -> str:
210218
return SCHEMA_URI
@@ -224,9 +232,12 @@ def ext(cls, obj: T, add_if_missing: bool = False) -> VersionExtension[T]:
224232
if isinstance(obj, pystac.Collection):
225233
cls.ensure_has_extension(obj, add_if_missing)
226234
return cast(VersionExtension[T], CollectionVersionExtension(obj))
227-
if isinstance(obj, pystac.Item):
235+
elif isinstance(obj, pystac.Item):
228236
cls.ensure_has_extension(obj, add_if_missing)
229237
return cast(VersionExtension[T], ItemVersionExtension(obj))
238+
elif isinstance(obj, pystac.Asset):
239+
cls.ensure_owner_has_extension(obj, add_if_missing)
240+
return cast(VersionExtension[T], AssetVersionExtension(obj))
230241
else:
231242
raise pystac.ExtensionTypeError(cls._ext_error_message(obj))
232243

@@ -278,6 +289,29 @@ def __repr__(self) -> str:
278289
return f"<ItemVersionExtension Item id={self.item.id}>"
279290

280291

292+
class AssetVersionExtension(VersionExtension[pystac.Asset]):
293+
"""A concrete implementation of :class:`VersionExtension` on an
294+
:class:`~pystac.Asset` that extends the fields of the Asset to include properties
295+
defined in the :stac-ext:`Versioning Indicators Extension <version>`.
296+
297+
This class should generally not be instantiated directly. Instead, call
298+
:meth:`VersionExtension.ext` on an :class:`~pystac.Asset` to extend it.
299+
"""
300+
301+
properties: dict[str, Any]
302+
303+
def __init__(self, asset: pystac.Asset):
304+
self.asset = asset
305+
self.properties = asset.extra_fields
306+
super().__init__(asset)
307+
308+
def __repr__(self) -> str:
309+
return (
310+
f"<AssetVersionExtension Asset in item id={self.asset.owner.id} and "
311+
f"href={self.asset.href}>"
312+
)
313+
314+
281315
class VersionExtensionHooks(ExtensionHooks):
282316
schema_uri = SCHEMA_URI
283317
prev_extension_ids = {"version"}

tests/data-files/version/collection.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"stac_version": "1.0.0-rc.1",
2+
"stac_version": "1.0.0",
33
"stac_extensions": [
4-
"https://stac-extensions.github.io/version/v1.0.0/schema.json"
4+
"https://stac-extensions.github.io/version/v1.2.0/schema.json"
55
],
66
"id": "merraclim",
77
"type": "Collection",

tests/data-files/version/item.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"stac_version": "1.0.0-rc.1",
2+
"stac_version": "1.0.0",
33
"stac_extensions": [
4-
"https://stac-extensions.github.io/version/v1.0.0/schema.json"
4+
"https://stac-extensions.github.io/version/v1.2.0/schema.json"
55
],
66
"id": "MERRAclim.2_5m_min_80s",
77
"type": "Feature",

tests/extensions/cassettes/test_version/CollectionVersionExtensionTest.test_add_deprecated_version.yaml

+44-63
Original file line numberDiff line numberDiff line change
@@ -9,94 +9,75 @@ interactions:
99
User-Agent:
1010
- Python-urllib/3.11
1111
method: GET
12-
uri: https://stac-extensions.github.io/version/v1.0.0/schema.json
12+
uri: https://stac-extensions.github.io/version/v1.2.0/schema.json
1313
response:
1414
body:
1515
string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\":
16-
\"https://stac-extensions.github.io/version/v1.0.0/schema.json#\",\n \"title\":
16+
\"https://stac-extensions.github.io/version/v1.2.0/schema.json#\",\n \"title\":
1717
\"Versioning Indicators Extension\",\n \"description\": \"STAC Versioning
1818
Indicators Extension for STAC Items and STAC Collections.\",\n \"oneOf\":
19-
[\n {\n \"$comment\": \"This is the schema for STAC Items. Remove
20-
this object if this extension only applies to Collections.\",\n \"allOf\":
19+
[\n {\n \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\":
2120
[\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n },\n
2221
\ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n
2322
\ \"properties\",\n \"assets\"\n ],\n \"properties\":
2423
{\n \"type\": {\n \"const\": \"Feature\"\n },\n
25-
\ \"properties\": {\n \"allOf\": [\n {\n
26-
\ \"$comment\": \"Require fields here for item properties.\",\n
27-
\ \"required\": [\n \"version\"\n ]\n
28-
\ },\n {\n \"$ref\": \"#/definitions/fields\"\n
29-
\ }\n ]\n },\n \"assets\":
30-
{\n \"$comment\": \"This validates the fields in Item Assets,
31-
but does not require them.\",\n \"type\": \"object\",\n \"additionalProperties\":
24+
\ \"properties\": {\n \"$ref\": \"#/definitions/fields\"\n
25+
\ },\n \"assets\": {\n \"type\": \"object\",\n
26+
\ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n
27+
\ }\n }\n }\n }\n ]\n },\n
28+
\ {\n \"$comment\": \"This is the schema for STAC Collections.\",\n
29+
\ \"type\": \"object\",\n \"allOf\": [\n {\n \"required\":
30+
[\n \"type\"\n ],\n \"properties\": {\n \"type\":
31+
{\n \"const\": \"Collection\"\n }\n }\n },\n
32+
\ {\n \"$ref\": \"#/definitions/stac_extensions\"\n },\n
33+
\ {\n \"$comment\": \"This is the schema for the top-level
34+
fields in a Collection.\",\n \"allOf\": [\n {\n \"$ref\":
35+
\"#/definitions/fields\"\n }\n ]\n },\n {\n
36+
\ \"$comment\": \"This validates the fields in Collection Assets.\",\n
37+
\ \"properties\": {\n \"assets\": {\n \"type\":
38+
\"object\",\n \"additionalProperties\": {\n \"$ref\":
39+
\"#/definitions/fields\"\n }\n }\n }\n },\n
40+
\ {\n \"$comment\": \"This is the schema for the fields in
41+
Item Asset Definitions.\",\n \"properties\": {\n \"item_assets\":
42+
{\n \"type\": \"object\",\n \"additionalProperties\":
3243
{\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
3344
\ }\n }\n ]\n },\n {\n \"$comment\": \"This
34-
is the schema for STAC Collections.\",\n \"type\": \"object\",\n \"allOf\":
35-
[\n {\n \"required\": [\n \"type\"\n ],\n
45+
is the schema for STAC Catalog.\",\n \"allOf\": [\n {\n \"type\":
46+
\"object\",\n \"required\": [\n \"type\"\n ],\n
3647
\ \"properties\": {\n \"type\": {\n \"const\":
37-
\"Collection\"\n }\n }\n },\n {\n \"$ref\":
38-
\"#/definitions/stac_extensions\"\n }\n ],\n \"anyOf\": [\n
39-
\ {\n \"$comment\": \"This is the schema for the top-level
40-
fields in a Collection. Remove this if this extension does not define top-level
41-
fields for Collections.\",\n \"allOf\": [\n {\n \"$comment\":
42-
\"Require fields here for Collections (top-level).\",\n \"required\":
43-
[\n \"version\"\n ]\n },\n {\n
44-
\ \"$ref\": \"#/definitions/fields\"\n }\n ]\n
45-
\ },\n {\n \"$comment\": \"This validates the fields
46-
in Collection Assets, but does not require them.\",\n \"required\":
47-
[\n \"assets\"\n ],\n \"properties\": {\n \"assets\":
48-
{\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\":
49-
{\n \"not\": {\n \"allOf\": [\n {\n
50-
\ \"$ref\": \"#/definitions/require_any_field\"\n },\n
51-
\ {\n \"$ref\": \"#/definitions/fields\"\n
52-
\ }\n ]\n }\n }\n
53-
\ }\n }\n }\n },\n {\n \"$comment\":
54-
\"This is the schema for the fields in Item Asset Definitions. It doesn't
55-
require any fields.\",\n \"required\": [\n \"item_assets\"\n
56-
\ ],\n \"properties\": {\n \"item_assets\": {\n
57-
\ \"type\": \"object\",\n \"not\": {\n \"additionalProperties\":
58-
{\n \"not\": {\n \"allOf\": [\n {\n
59-
\ \"$ref\": \"#/definitions/require_any_field\"\n },\n
60-
\ {\n \"$ref\": \"#/definitions/fields\"\n
61-
\ }\n ]\n }\n }\n
62-
\ }\n }\n }\n },\n {\n \"$comment\":
63-
\"This is the schema for the fields in Summaries. By default, only checks
64-
the existance of the properties, but not the schema of the summaries.\",\n
65-
\ \"required\": [\n \"summaries\"\n ],\n \"properties\":
66-
{\n \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n
67-
\ }\n }\n }\n ]\n }\n ],\n \"definitions\":
48+
\"Catalog\"\n }\n }\n },\n {\n \"$ref\":
49+
\"#/definitions/stac_extensions\"\n },\n {\n \"$ref\":
50+
\"#/definitions/fields\"\n }\n ]\n }\n ],\n \"definitions\":
6851
{\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\":
6952
[\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\":
7053
{\n \"type\": \"array\",\n \"contains\": {\n \"const\":
71-
\"https://stac-extensions.github.io/version/v1.0.0/schema.json\"\n }\n
72-
\ }\n }\n },\n \"require_any_field\": {\n \"$comment\":
73-
\"Please list all fields here so that we can force the existance of one of
74-
them in other parts of the schemas.\",\n \"anyOf\": [\n {\"required\":
75-
[\"version\"]},\n {\"required\": [\"deprecated\"]}\n ]\n },\n
76-
\ \"fields\": {\n \"type\": \"object\",\n \"properties\": {\n
77-
\ \"version\": {\n \"type\": \"string\",\n \"title\":
78-
\"Version\"\n },\n \"deprecated\": {\n \"type\": \"boolean\",\n
79-
\ \"title\": \"Deprecated\",\n \"default\": false\n }\n
54+
\"https://stac-extensions.github.io/version/v1.2.0/schema.json\"\n }\n
55+
\ }\n }\n },\n \"fields\": {\n \"type\": \"object\",\n
56+
\ \"properties\": {\n \"version\": {\n \"type\": \"string\",\n
57+
\ \"title\": \"Version\"\n },\n \"deprecated\": {\n
58+
\ \"type\": \"boolean\",\n \"title\": \"Deprecated\",\n \"default\":
59+
false\n },\n \"experimental\": {\n \"type\": \"boolean\",\n
60+
\ \"title\": \"Experimental\",\n \"default\": false\n }\n
8061
\ }\n }\n }\n}\n"
8162
headers:
8263
Accept-Ranges:
8364
- bytes
8465
Access-Control-Allow-Origin:
8566
- '*'
8667
Age:
87-
- '517'
68+
- '443'
8869
Cache-Control:
8970
- max-age=600
9071
Connection:
9172
- close
9273
Content-Length:
93-
- '5009'
74+
- '3405'
9475
Content-Type:
9576
- application/json; charset=utf-8
9677
Date:
97-
- Wed, 27 Sep 2023 21:20:50 GMT
78+
- Fri, 13 Oct 2023 13:39:13 GMT
9879
ETag:
99-
- '"645249bd-1391"'
80+
- '"645249bd-d4d"'
10081
Last-Modified:
10182
- Wed, 03 May 2023 11:47:09 GMT
10283
Server:
@@ -110,17 +91,17 @@ interactions:
11091
X-Cache:
11192
- HIT
11293
X-Cache-Hits:
113-
- '2'
94+
- '1'
11495
X-Fastly-Request-ID:
115-
- 8b9fffd9434fd81ec501ce6f8c825aa774cc06e7
96+
- 8ba7479ba4057d23836c2d204c3baeda68d2722f
11697
X-GitHub-Request-Id:
117-
- 96AE:1981:28905C:3865AF:65149AAC
98+
- B200:2C1D:709A53:995830:6529359A
11899
X-Served-By:
119-
- cache-lga21962-LGA
100+
- cache-iad-kjyo7100036-IAD
120101
X-Timer:
121-
- S1695849651.615996,VS0,VE1
102+
- S1697204353.008353,VS0,VE1
122103
expires:
123-
- Wed, 27 Sep 2023 21:22:13 GMT
104+
- Fri, 13 Oct 2023 12:28:35 GMT
124105
permissions-policy:
125106
- interest-cohort=()
126107
x-proxy-cache:

0 commit comments

Comments
 (0)