Skip to content

Commit 79108a1

Browse files
author
Jon Duckworth
authored
Merge pull request #511 from duckontheweb/add/gh-169-get-collections
Add get_collections + get_all_collections methods to Catalog
2 parents 873a8fd + 685079c commit 79108a1

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
- Define equality and `__repr__` of `RangeSummary` instances based on `to_dict`
1515
representation ([#513](https://github.com/stac-utils/pystac/pull/513))
1616
- Sat Extension summaries ([#509](https://github.com/stac-utils/pystac/pull/509))
17+
- `Catalog.get_collections` for getting all child
18+
`Collections` for a catalog, and `Catalog.get_all_collections` for recursively getting
19+
all child `Collections` for a catalog and its children ([#511](https://github.com/stac-utils/pystac/pull/))
1720

1821
### Changed
1922

pystac/catalog.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,21 @@ def get_children(self) -> Iterable[Union["Catalog", "Collection_Type"]]:
320320
self.get_stac_objects(pystac.RelType.CHILD),
321321
)
322322

323+
def get_collections(self) -> Iterable["Collection_Type"]:
324+
"""Return all children of this catalog that are :class:`~pystac.Collection`
325+
instances."""
326+
return map(
327+
lambda x: cast(pystac.Collection, x),
328+
self.get_stac_objects(pystac.RelType.CHILD, pystac.Collection),
329+
)
330+
331+
def get_all_collections(self) -> Iterable["Collection_Type"]:
332+
"""Get all collections from this catalog and all subcatalogs. Will traverse
333+
any subcatalogs recursively."""
334+
yield from self.get_collections()
335+
for child in self.get_children():
336+
yield from child.get_collections()
337+
323338
def get_child_links(self) -> List[Link]:
324339
"""Return all child links of this catalog.
325340

pystac/stac_object.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from abc import ABC, abstractmethod
22
from enum import Enum
3-
from typing import Any, Dict, Iterable, List, Optional, cast, TYPE_CHECKING, Union
3+
from typing import Any, Dict, Iterable, List, Optional, Type, cast, TYPE_CHECKING, Union
44

55
import pystac
66
from pystac import STACError
@@ -272,25 +272,29 @@ def set_parent(self, parent: Optional["Catalog_Type"]) -> None:
272272
self.add_link(Link.parent(parent))
273273

274274
def get_stac_objects(
275-
self, rel: Union[str, pystac.RelType]
275+
self, rel: Union[str, pystac.RelType], typ: Optional[Type["STACObject"]] = None
276276
) -> Iterable["STACObject"]:
277277
"""Gets the :class:`~pystac.STACObject` instances that are linked to
278278
by links with their ``rel`` property matching the passed in argument.
279279
280280
Args:
281281
rel : The relation to match each :class:`~pystac.Link`'s
282282
``rel`` property against.
283+
typ : If not ``None``, objects will only be yielded if they are instances of
284+
``typ``.
283285
284286
Returns:
285287
Iterable[STACObjects]: A possibly empty iterable of STACObjects that are
286-
connected to this object through links with the given ``rel``.
288+
connected to this object through links with the given ``rel`` and are of
289+
type ``typ`` (if given).
287290
"""
288291
links = self.links[:]
289292
for i in range(0, len(links)):
290293
link = links[i]
291294
if link.rel == rel:
292295
link.resolve_stac_object(root=self.get_root())
293-
yield cast("STACObject", link.target)
296+
if typ is None or isinstance(link.target, typ):
297+
yield cast("STACObject", link.target)
294298

295299
def save_object(
296300
self,

tests/test_catalog.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,20 @@ def testfrom_invalid_dict_raises_exception(self) -> None:
996996
with self.assertRaises(pystac.STACTypeError):
997997
_ = pystac.Catalog.from_dict(collection_dict)
998998

999+
def test_get_collections(self) -> None:
1000+
catalog = TestCases.test_case_2()
1001+
collections = list(catalog.get_collections())
1002+
1003+
self.assertGreater(len(collections), 0)
1004+
self.assertTrue(all(isinstance(c, pystac.Collection) for c in collections))
1005+
1006+
def test_get_all_collections(self) -> None:
1007+
catalog = TestCases.test_case_1()
1008+
all_collections = list(catalog.get_all_collections())
1009+
1010+
self.assertGreater(len(all_collections), 0)
1011+
self.assertTrue(all(isinstance(c, pystac.Collection) for c in all_collections))
1012+
9991013

10001014
class FullCopyTest(unittest.TestCase):
10011015
def check_link(self, link: pystac.Link, tag: str) -> None:

0 commit comments

Comments
 (0)