Skip to content

Commit eaf8b42

Browse files
authored
Merge pull request #193 from schwehr/version-extension
Add support for the version extension.
2 parents 9944c51 + fbd7abd commit eaf8b42

File tree

4 files changed

+467
-6
lines changed

4 files changed

+467
-6
lines changed

docs/api.rst

+23-2
Original file line numberDiff line numberDiff line change
@@ -254,12 +254,12 @@ LabelStatistics
254254
Pointcloud Extension
255255
--------------------
256256

257-
Implements the `Projection Extension <https://github.com/radiantearth/stac-spec/tree/v1.0.0-beta.2/extensions/pointcloud>`_.
257+
Implements the `Point Cloud Extension <https://github.com/radiantearth/stac-spec/tree/v1.0.0-beta.2/extensions/pointcloud>`_.
258258

259259
PointcloudItemExt
260260
~~~~~~~~~~~~~~~~~
261261

262-
.. autoclass:: pystac.extensions.projection.PointcloudItemExt
262+
.. autoclass:: pystac.extensions.pointcloud.PointcloudItemExt
263263
:members:
264264
:undoc-members:
265265
:show-inheritance:
@@ -306,6 +306,27 @@ SingleFileSTACCatalogExt
306306
:members:
307307
:undoc-members:
308308

309+
Version Extension
310+
-----------------
311+
312+
Implements the `Version Extension <https://github.com/radiantearth/stac-spec/tree/v1.0.0-beta.2/extensions/version>`_.
313+
314+
VersionCollectionExt
315+
~~~~~~~~~~~~~~~~~~~~
316+
317+
.. autoclass:: pystac.extensions.version.VersionCollectionExt
318+
:members:
319+
:undoc-members:
320+
:show-inheritance:
321+
322+
VersionItemExt
323+
~~~~~~~~~~~~~~
324+
325+
.. autoclass:: pystac.extensions.version.VersionItemExt
326+
:members:
327+
:undoc-members:
328+
:show-inheritance:
329+
309330
View Geometry Extension
310331
-----------------------
311332

pystac/__init__.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,20 @@ class STACError(Exception):
3232
from pystac import extensions
3333
import pystac.extensions.eo
3434
import pystac.extensions.label
35-
import pystac.extensions.projection
3635
import pystac.extensions.pointcloud
37-
import pystac.extensions.view
36+
import pystac.extensions.projection
3837
import pystac.extensions.single_file_stac
3938
import pystac.extensions.timestamps
39+
import pystac.extensions.version
40+
import pystac.extensions.view
4041

4142
STAC_EXTENSIONS = extensions.base.RegisteredSTACExtensions([
4243
extensions.eo.EO_EXTENSION_DEFINITION, extensions.label.LABEL_EXTENSION_DEFINITION,
4344
extensions.pointcloud.POINTCLOUD_EXTENSION_DEFINITION,
4445
extensions.projection.PROJECTION_EXTENSION_DEFINITION,
45-
extensions.view.VIEW_EXTENSION_DEFINITION, extensions.single_file_stac.SFS_EXTENSION_DEFINITION,
46-
extensions.timestamps.TIMESTAMPS_EXTENSION_DEFINITION
46+
extensions.single_file_stac.SFS_EXTENSION_DEFINITION,
47+
extensions.timestamps.TIMESTAMPS_EXTENSION_DEFINITION,
48+
extensions.version.VERSION_EXTENSION_DEFINITION, extensions.view.VIEW_EXTENSION_DEFINITION
4749
])
4850

4951

pystac/extensions/version.py

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
"""Implement the version extension.
2+
3+
https://github.com/radiantearth/stac-spec/tree/dev/extensions/version
4+
"""
5+
6+
import pystac
7+
from pystac import collection
8+
from pystac import Extensions
9+
from pystac import item
10+
from pystac import link
11+
from pystac.extensions import base
12+
13+
VERSION = 'version'
14+
DEPRECATED = 'deprecated'
15+
LATEST = 'latest-version'
16+
PREDECESSOR = 'predecessor-version'
17+
SUCCESSOR = 'successor-version'
18+
19+
# Media type for links.
20+
MEDIA_TYPE = 'application/json'
21+
22+
23+
class VersionItemExt(base.ItemExtension):
24+
"""Add an asset version string to a STAC Item."""
25+
def __init__(self, an_item):
26+
self.item = an_item
27+
28+
def apply(self, version, deprecated=None, latest=None, predecessor=None, successor=None):
29+
self.version = version
30+
if deprecated is not None:
31+
self.deprecated = deprecated
32+
if latest:
33+
self.latest = latest
34+
if predecessor:
35+
self.predecessor = predecessor
36+
if successor:
37+
self.successor = successor
38+
39+
@property
40+
def version(self):
41+
return self.item.properties.get(VERSION)
42+
43+
@version.setter
44+
def version(self, v):
45+
self.item.properties[VERSION] = v
46+
47+
@property
48+
def deprecated(self):
49+
return bool(self.item.properties.get(DEPRECATED))
50+
51+
@deprecated.setter
52+
def deprecated(self, v):
53+
if not isinstance(v, bool):
54+
raise pystac.STACError(DEPRECATED + ' must be a bool')
55+
self.item.properties[DEPRECATED] = v
56+
57+
@property
58+
def latest(self):
59+
return next(self.item.get_stac_objects(LATEST), None)
60+
61+
@latest.setter
62+
def latest(self, source_item):
63+
self.item.add_link(link.Link(LATEST, source_item, MEDIA_TYPE))
64+
65+
@property
66+
def predecessor(self):
67+
return next(self.item.get_stac_objects(PREDECESSOR), None)
68+
69+
@predecessor.setter
70+
def predecessor(self, source_item):
71+
self.item.add_link(link.Link(PREDECESSOR, source_item, MEDIA_TYPE))
72+
73+
@property
74+
def successor(self):
75+
return next(self.item.get_stac_objects(SUCCESSOR), None)
76+
77+
@successor.setter
78+
def successor(self, source_item):
79+
self.item.add_link(link.Link(SUCCESSOR, source_item, MEDIA_TYPE))
80+
81+
@classmethod
82+
def from_item(cls, an_item):
83+
return cls(an_item)
84+
85+
@classmethod
86+
def _object_links(cls):
87+
return [LATEST, PREDECESSOR, SUCCESSOR]
88+
89+
90+
class VersionCollectionExt(base.CollectionExtension):
91+
"""Add an asset version string to a STAC Collection."""
92+
def __init__(self, a_collection):
93+
self.collection = a_collection
94+
95+
@property
96+
def version(self):
97+
return self.collection.extra_fields.get(VERSION)
98+
99+
@version.setter
100+
def version(self, v):
101+
self.collection.extra_fields[VERSION] = v
102+
103+
@property
104+
def deprecated(self):
105+
return bool(self.collection.extra_fields.get(DEPRECATED))
106+
107+
@deprecated.setter
108+
def deprecated(self, v):
109+
if not isinstance(v, bool):
110+
raise pystac.STACError(DEPRECATED + ' must be a bool')
111+
self.collection.extra_fields[DEPRECATED] = v
112+
113+
@property
114+
def latest(self):
115+
return next(self.collection.get_stac_objects(LATEST), None)
116+
117+
@latest.setter
118+
def latest(self, source_collection):
119+
self.collection.add_link(link.Link(LATEST, source_collection, MEDIA_TYPE))
120+
121+
@property
122+
def predecessor(self):
123+
return next(self.collection.get_stac_objects(PREDECESSOR), None)
124+
125+
@predecessor.setter
126+
def predecessor(self, source_collection):
127+
self.collection.add_link(link.Link(PREDECESSOR, source_collection, MEDIA_TYPE))
128+
129+
@property
130+
def successor(self):
131+
return next(self.collection.get_stac_objects(SUCCESSOR), None)
132+
133+
@successor.setter
134+
def successor(self, source_collection):
135+
self.collection.add_link(link.Link(SUCCESSOR, source_collection, MEDIA_TYPE))
136+
137+
@classmethod
138+
def from_collection(cls, a_collection):
139+
return cls(a_collection)
140+
141+
@classmethod
142+
def _object_links(cls):
143+
return [LATEST, PREDECESSOR, SUCCESSOR]
144+
145+
def apply(self, version, deprecated=None, latest=None, predecessor=None, successor=None):
146+
self.version = version
147+
if deprecated is not None:
148+
self.deprecated = deprecated
149+
if latest:
150+
self.latest = latest
151+
if predecessor:
152+
self.predecessor = predecessor
153+
if successor:
154+
self.successor = successor
155+
156+
157+
VERSION_EXTENSION_DEFINITION = base.ExtensionDefinition(Extensions.VERSION, [
158+
base.ExtendedObject(item.Item, VersionItemExt),
159+
base.ExtendedObject(collection.Collection, VersionCollectionExt)
160+
])

0 commit comments

Comments
 (0)