From 119a2cdcac9bea5cc653d4f7d1087a0ea1a6287d Mon Sep 17 00:00:00 2001 From: Tobias Schmidt <13055656+schmidtnz@users.noreply.github.com> Date: Fri, 22 Nov 2024 10:13:44 +1300 Subject: [PATCH] refactor: only allow one of specific link types TDE-1298 (#1182) ### Motivation Refactoring to support TDE-1298 - only allow one link of each of the types `Collection`, `Parent`, `Self`. ### Modifications Added logic in `ImageryItem`s `add_link` method to recognise when a link of each type already exists. Added `__str__` method to `StacMediaType` and `Relation` types, and made sure the `Link` class will contain strings for `rel` and `type`. ### Verification `pytest` --- scripts/stac/imagery/item.py | 9 ++++++++- scripts/stac/link.py | 11 +++++++---- scripts/stac/util/media_type.py | 3 +++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/scripts/stac/imagery/item.py b/scripts/stac/imagery/item.py index c9ca76794..d3b1cfc6a 100644 --- a/scripts/stac/imagery/item.py +++ b/scripts/stac/imagery/item.py @@ -71,4 +71,11 @@ def add_collection(self, collection_id: str) -> None: self.add_link(Link(path="./collection.json", rel=Relation.PARENT, media_type=StacMediaType.JSON)) def add_link(self, link: Link) -> None: - self.stac["links"].append(link.stac) + if self.stac.get("links") and link.stac["rel"] in [ + Relation.COLLECTION, + Relation.PARENT, + Relation.SELF, + ]: # STAC specification prescribes there can be only one of these + self.stac["links"][:] = [l for l in self.stac["links"] if l.get("rel") != link.stac["rel"]] + + self.stac.setdefault("links", []).append(link.stac) diff --git a/scripts/stac/link.py b/scripts/stac/link.py index 79b63ba2c..e380428c5 100644 --- a/scripts/stac/link.py +++ b/scripts/stac/link.py @@ -15,6 +15,9 @@ class Relation(str, Enum): DERIVED_FROM = "derived_from" """ https://github.com/radiantearth/stac-spec/blob/master/best-practices.md#derived-from-relation-derived_from""" + def __str__(self) -> str: + return self.value + # pylint: disable=too-few-public-methods class Link: @@ -22,7 +25,7 @@ class Link: Attributes: path: A string that represents the actual link in the format of an URL. - rel: A string that represents the relationship that the link has to the object it will be added to. + rel: `Relation` that represents the relationship that the link has to the object it will be added to. media_type: `StacMediaType` of the link file. file_content: Optional. The content of the file that will be used to store the checksum in `file:checksum`. It assumes using the STAC `file` extension. @@ -30,11 +33,11 @@ class Link: stac: dict[str, str] - def __init__(self, path: str, rel: str, media_type: StacMediaType, file_content: bytes | None = None) -> None: + def __init__(self, path: str, rel: Relation, media_type: StacMediaType, file_content: bytes | None = None) -> None: self.stac = { "href": path, - "rel": rel, - "type": media_type, + "rel": str(rel), + "type": str(media_type), } if file_content: diff --git a/scripts/stac/util/media_type.py b/scripts/stac/util/media_type.py index cd56c21f5..81ad975ef 100644 --- a/scripts/stac/util/media_type.py +++ b/scripts/stac/util/media_type.py @@ -11,3 +11,6 @@ class StacMediaType(str, Enum): For STAC Item """ + + def __str__(self) -> str: + return self.value