Skip to content

Commit

Permalink
Support multiple schema versions following changes in stac-utils#1091
Browse files Browse the repository at this point in the history
  • Loading branch information
jpolchlo committed May 30, 2023
1 parent be2b054 commit 3f127ea
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- `owner` attribute to `AssetDefinition` in the item-assets extension ([#1110](https://github.com/stac-utils/pystac/pull/1110))
- Windows `\\` path delimiters are converted to POSIX style `/` delimiters ([#1125](https://github.com/stac-utils/pystac/pull/1125))
- Updated raster extension to work with the item_assets extension's AssetDefinition objects ([#1110](https://github.com/stac-utils/pystac/pull/1110))
- Classification extension ([#1093](https://github.com/stac-utils/pystac/pull/1093)), with support for adding classification information to item_assets' `AssetDefinition`s and raster's `RasterBand` objects.

### Changed

Expand Down
25 changes: 17 additions & 8 deletions pystac/extensions/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Iterable,
List,
Optional,
Pattern,
TypeVar,
Union,
cast,
Expand All @@ -29,14 +30,20 @@

T = TypeVar("T", pystac.Item, pystac.Asset, item_assets.AssetDefinition, RasterBand)

SCHEMA_URI: str = "https://stac-extensions.github.io/classification/v1.0.0/schema.json"
PREFIX: str = "classification:"
SCHEMA_URI_PATTERN: str = (
"https://stac-extensions.github.io/classification/v{version}/schema.json"
)
DEFAULT_VERSION: str = "1.1.0"
SUPPORTED_VERSIONS: List[str] = ["1.1.0", "1.0.0"]

# Field names
PREFIX: str = "classification:"
BITFIELDS_PROP: str = PREFIX + "bitfields"
CLASSES_PROP: str = PREFIX + "classes"
RASTER_BANDS_PROP: str = "raster:bands"

COLOR_HINT_PATTERN: Pattern[str] = re.compile("^([0-9A-Fa-f]{6})$")


class Classification:
"""Represents a single category of a classification.
Expand Down Expand Up @@ -73,8 +80,7 @@ def apply(
self.color_hint = color_hint

if color_hint is not None:
color_hint_pattern = re.compile("^([0-9A-F]{6})$")
match = color_hint_pattern.match(color_hint)
match = COLOR_HINT_PATTERN.match(color_hint)
assert (
color_hint is None or match is not None and match.group() == color_hint
), "Must format color hints as '^([0-9A-F]{6})$'"
Expand Down Expand Up @@ -171,8 +177,7 @@ def color_hint(self) -> Optional[str]:
@color_hint.setter
def color_hint(self, v: Optional[str]) -> None:
if v is not None:
color_hint_pattern = re.compile("^([0-9A-F]{6})$")
match = color_hint_pattern.match(v)
match = COLOR_HINT_PATTERN.match(v)
assert (
v is None or match is not None and match.group() == v
), "Must format color hints as '^([0-9A-F]{6})$'"
Expand Down Expand Up @@ -502,7 +507,11 @@ def _get_bitfields(self) -> Optional[List[Bitfield]]:

@classmethod
def get_schema_uri(cls) -> str:
return SCHEMA_URI
return SCHEMA_URI_PATTERN.format(version=DEFAULT_VERSION)

@classmethod
def get_schema_uris(cls) -> List[str]:
return [SCHEMA_URI_PATTERN.format(version=v) for v in SUPPORTED_VERSIONS]

@classmethod
def ext(cls, obj: T, add_if_missing: bool = False) -> ClassificationExtension[T]:
Expand Down Expand Up @@ -634,7 +643,7 @@ def __repr__(self) -> str:


class ClassificationExtensionHooks(ExtensionHooks):
schema_uri: str = SCHEMA_URI
schema_uri: str = SCHEMA_URI_PATTERN.format(version=DEFAULT_VERSION)
prev_extension_ids = {"classification"}
stac_object_types = {pystac.STACObjectType.ITEM}

Expand Down
10 changes: 8 additions & 2 deletions tests/extensions/test_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ def test_stac_extensions(landsat_item: Item) -> None:


def test_get_schema_uri(landsat_item: Item) -> None:
assert ClassificationExtension.get_schema_uri() in landsat_item.stac_extensions
assert any(
[
uri in landsat_item.stac_extensions
for uri in ClassificationExtension.get_schema_uris()
]
)


def test_ext_raises_if_item_does_not_conform(plain_item: Item) -> None:
Expand All @@ -78,7 +83,8 @@ def test_apply(plain_item: Item) -> None:
)
]
)
# plain_item.validate() ## THIS FAILS

plain_item.validate()
assert (
ClassificationExtension.ext(plain_item).bitfields is not None
and len(cast(List[Bitfield], ClassificationExtension.ext(plain_item).bitfields))
Expand Down

0 comments on commit 3f127ea

Please sign in to comment.