Skip to content

Commit

Permalink
feat: add remove_hierarchical_links
Browse files Browse the repository at this point in the history
  • Loading branch information
gadomski committed Feb 22, 2023
1 parent b29ee65 commit 6457dcd
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 2 deletions.
3 changes: 2 additions & 1 deletion pystac/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

HREF = Union[str, os.PathLike]

#: Hierarchical links provide structure to STAC catalogs.
HIERARCHICAL_LINKS = [
pystac.RelType.ROOT,
pystac.RelType.CHILD,
Expand Down Expand Up @@ -350,7 +351,7 @@ def is_hierarchical(self) -> bool:
Hierarchical links are used to build relationships in STAC, e.g.
"parent", "child", "item", etc. For a complete list of hierarchical
relation types, see `:py:const:HIERARCHICAL_LINKS`.
relation types, see :py:const:`HIERARCHICAL_LINKS`.
Returns:
bool: True if the link's rel type is hierarchical.
Expand Down
29 changes: 29 additions & 0 deletions pystac/stac_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,35 @@ def remove_links(self, rel: Union[str, pystac.RelType]) -> None:

self.links = [link for link in self.links if link.rel != rel]

def remove_hierarchical_links(self, add_canonical: bool = False) -> List[Link]:
"""Removes all hierarchical links from this object.
See :py:const:`pystac.link.HIERARCHICAL_LINKS` for a list of all
hierarchical links. If the object has a ``self`` href and
``add_canonical`` is True, a link with ``rel="canonical"`` is added.
Args:
add_canonical : If true, and this item has a ``self`` href, that
href is used to build a ``canonical`` link.
Returns:
List[Link]: All removed links
"""
keep = list()
self_href = self.get_self_href()
if add_canonical and self_href is not None:
keep.append(
Link("canonical", self_href, media_type=pystac.MediaType.GEOJSON)
)
remove = list()
for link in self.links:
if link.is_hierarchical():
remove.append(link)
else:
keep.append(link)
self.links = keep
return remove

def get_single_link(
self,
rel: Optional[Union[str, pystac.RelType]] = None,
Expand Down
9 changes: 8 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# TODO move all test case code to this file

from datetime import datetime

import pytest

from pystac import Catalog, Collection, Item

from .utils import ARBITRARY_BBOX, ARBITRARY_EXTENT, ARBITRARY_GEOM
from .utils import ARBITRARY_BBOX, ARBITRARY_EXTENT, ARBITRARY_GEOM, TestCases


@pytest.fixture
Expand All @@ -20,3 +22,8 @@ def collection() -> Catalog:
@pytest.fixture
def item() -> Item:
return Item("test-item", ARBITRARY_GEOM, ARBITRARY_BBOX, datetime.now(), {})


@pytest.fixture
def label_catalog() -> Catalog:
return TestCases.case_1()
8 changes: 8 additions & 0 deletions tests/test_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -1459,3 +1459,11 @@ def from_dict(
return super().from_dict(d)

_ = CustomCatalog.from_dict(catalog.to_dict())


@pytest.mark.parametrize("add_canonical", (True, False))
def test_remove_hierarchical_links(label_catalog: Catalog, add_canonical: bool) -> None:
label_catalog.remove_hierarchical_links(add_canonical=add_canonical)
for link in label_catalog.links:
assert not link.is_hierarchical()
assert bool(label_catalog.get_single_link("canonical")) == add_canonical
10 changes: 10 additions & 0 deletions tests/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from datetime import datetime
from typing import Any, Dict, Optional

import pytest
from dateutil import tz

import pystac
Expand Down Expand Up @@ -529,3 +530,12 @@ def from_dict(
return super().from_dict(d)

_ = CustomCollection.from_dict(collection.to_dict())


@pytest.mark.parametrize("add_canonical", (True, False))
def test_remove_hierarchical_links(label_catalog: Catalog, add_canonical: bool) -> None:
collection = list(label_catalog.get_all_collections())[0]
collection.remove_hierarchical_links(add_canonical=add_canonical)
for link in collection.links:
assert not link.is_hierarchical()
assert bool(collection.get_single_link("canonical")) == add_canonical
9 changes: 9 additions & 0 deletions tests/test_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,3 +455,12 @@ def test_item_from_dict_with_missing_type_raises_useful_error() -> None:
item_dict = {"stac_version": "0.8.0", "id": "lalalalala"}
with pytest.raises(pystac.STACTypeError, match="'type' is missing"):
Item.from_dict(item_dict)


@pytest.mark.parametrize("add_canonical", (True, False))
def test_remove_hierarchical_links(label_catalog: Catalog, add_canonical: bool) -> None:
item = list(label_catalog.get_all_items())[0]
item.remove_hierarchical_links(add_canonical=add_canonical)
for link in item.links:
assert not link.is_hierarchical()
assert bool(item.get_single_link("canonical")) == add_canonical

0 comments on commit 6457dcd

Please sign in to comment.