Skip to content

Commit

Permalink
Merge pull request stac-utils#193 from schwehr/version-extension
Browse files Browse the repository at this point in the history
Add support for the version extension.
  • Loading branch information
lossyrob authored Oct 16, 2020
2 parents 9944c51 + fbd7abd commit eaf8b42
Show file tree
Hide file tree
Showing 4 changed files with 467 additions and 6 deletions.
25 changes: 23 additions & 2 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,12 @@ LabelStatistics
Pointcloud Extension
--------------------

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

PointcloudItemExt
~~~~~~~~~~~~~~~~~

.. autoclass:: pystac.extensions.projection.PointcloudItemExt
.. autoclass:: pystac.extensions.pointcloud.PointcloudItemExt
:members:
:undoc-members:
:show-inheritance:
Expand Down Expand Up @@ -306,6 +306,27 @@ SingleFileSTACCatalogExt
:members:
:undoc-members:

Version Extension
-----------------

Implements the `Version Extension <https://github.com/radiantearth/stac-spec/tree/v1.0.0-beta.2/extensions/version>`_.

VersionCollectionExt
~~~~~~~~~~~~~~~~~~~~

.. autoclass:: pystac.extensions.version.VersionCollectionExt
:members:
:undoc-members:
:show-inheritance:

VersionItemExt
~~~~~~~~~~~~~~

.. autoclass:: pystac.extensions.version.VersionItemExt
:members:
:undoc-members:
:show-inheritance:

View Geometry Extension
-----------------------

Expand Down
10 changes: 6 additions & 4 deletions pystac/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,20 @@ class STACError(Exception):
from pystac import extensions
import pystac.extensions.eo
import pystac.extensions.label
import pystac.extensions.projection
import pystac.extensions.pointcloud
import pystac.extensions.view
import pystac.extensions.projection
import pystac.extensions.single_file_stac
import pystac.extensions.timestamps
import pystac.extensions.version
import pystac.extensions.view

STAC_EXTENSIONS = extensions.base.RegisteredSTACExtensions([
extensions.eo.EO_EXTENSION_DEFINITION, extensions.label.LABEL_EXTENSION_DEFINITION,
extensions.pointcloud.POINTCLOUD_EXTENSION_DEFINITION,
extensions.projection.PROJECTION_EXTENSION_DEFINITION,
extensions.view.VIEW_EXTENSION_DEFINITION, extensions.single_file_stac.SFS_EXTENSION_DEFINITION,
extensions.timestamps.TIMESTAMPS_EXTENSION_DEFINITION
extensions.single_file_stac.SFS_EXTENSION_DEFINITION,
extensions.timestamps.TIMESTAMPS_EXTENSION_DEFINITION,
extensions.version.VERSION_EXTENSION_DEFINITION, extensions.view.VIEW_EXTENSION_DEFINITION
])


Expand Down
160 changes: 160 additions & 0 deletions pystac/extensions/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
"""Implement the version extension.
https://github.com/radiantearth/stac-spec/tree/dev/extensions/version
"""

import pystac
from pystac import collection
from pystac import Extensions
from pystac import item
from pystac import link
from pystac.extensions import base

VERSION = 'version'
DEPRECATED = 'deprecated'
LATEST = 'latest-version'
PREDECESSOR = 'predecessor-version'
SUCCESSOR = 'successor-version'

# Media type for links.
MEDIA_TYPE = 'application/json'


class VersionItemExt(base.ItemExtension):
"""Add an asset version string to a STAC Item."""
def __init__(self, an_item):
self.item = an_item

def apply(self, version, deprecated=None, latest=None, predecessor=None, successor=None):
self.version = version
if deprecated is not None:
self.deprecated = deprecated
if latest:
self.latest = latest
if predecessor:
self.predecessor = predecessor
if successor:
self.successor = successor

@property
def version(self):
return self.item.properties.get(VERSION)

@version.setter
def version(self, v):
self.item.properties[VERSION] = v

@property
def deprecated(self):
return bool(self.item.properties.get(DEPRECATED))

@deprecated.setter
def deprecated(self, v):
if not isinstance(v, bool):
raise pystac.STACError(DEPRECATED + ' must be a bool')
self.item.properties[DEPRECATED] = v

@property
def latest(self):
return next(self.item.get_stac_objects(LATEST), None)

@latest.setter
def latest(self, source_item):
self.item.add_link(link.Link(LATEST, source_item, MEDIA_TYPE))

@property
def predecessor(self):
return next(self.item.get_stac_objects(PREDECESSOR), None)

@predecessor.setter
def predecessor(self, source_item):
self.item.add_link(link.Link(PREDECESSOR, source_item, MEDIA_TYPE))

@property
def successor(self):
return next(self.item.get_stac_objects(SUCCESSOR), None)

@successor.setter
def successor(self, source_item):
self.item.add_link(link.Link(SUCCESSOR, source_item, MEDIA_TYPE))

@classmethod
def from_item(cls, an_item):
return cls(an_item)

@classmethod
def _object_links(cls):
return [LATEST, PREDECESSOR, SUCCESSOR]


class VersionCollectionExt(base.CollectionExtension):
"""Add an asset version string to a STAC Collection."""
def __init__(self, a_collection):
self.collection = a_collection

@property
def version(self):
return self.collection.extra_fields.get(VERSION)

@version.setter
def version(self, v):
self.collection.extra_fields[VERSION] = v

@property
def deprecated(self):
return bool(self.collection.extra_fields.get(DEPRECATED))

@deprecated.setter
def deprecated(self, v):
if not isinstance(v, bool):
raise pystac.STACError(DEPRECATED + ' must be a bool')
self.collection.extra_fields[DEPRECATED] = v

@property
def latest(self):
return next(self.collection.get_stac_objects(LATEST), None)

@latest.setter
def latest(self, source_collection):
self.collection.add_link(link.Link(LATEST, source_collection, MEDIA_TYPE))

@property
def predecessor(self):
return next(self.collection.get_stac_objects(PREDECESSOR), None)

@predecessor.setter
def predecessor(self, source_collection):
self.collection.add_link(link.Link(PREDECESSOR, source_collection, MEDIA_TYPE))

@property
def successor(self):
return next(self.collection.get_stac_objects(SUCCESSOR), None)

@successor.setter
def successor(self, source_collection):
self.collection.add_link(link.Link(SUCCESSOR, source_collection, MEDIA_TYPE))

@classmethod
def from_collection(cls, a_collection):
return cls(a_collection)

@classmethod
def _object_links(cls):
return [LATEST, PREDECESSOR, SUCCESSOR]

def apply(self, version, deprecated=None, latest=None, predecessor=None, successor=None):
self.version = version
if deprecated is not None:
self.deprecated = deprecated
if latest:
self.latest = latest
if predecessor:
self.predecessor = predecessor
if successor:
self.successor = successor


VERSION_EXTENSION_DEFINITION = base.ExtensionDefinition(Extensions.VERSION, [
base.ExtendedObject(item.Item, VersionItemExt),
base.ExtendedObject(collection.Collection, VersionCollectionExt)
])
Loading

0 comments on commit eaf8b42

Please sign in to comment.