Skip to content

Commit

Permalink
Remove ItemCollection from top-level functions
Browse files Browse the repository at this point in the history
  • Loading branch information
duckontheweb committed Jun 14, 2021
1 parent 97354cd commit 2bb16a1
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 66 deletions.
54 changes: 25 additions & 29 deletions pystac/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
STACValidationError,
)

from typing import Any, Dict, Optional, Union
from typing import Any, Dict, Optional
from pystac.version import (
__version__,
get_stac_version,
Expand Down Expand Up @@ -72,7 +72,7 @@
)


def read_file(href: str) -> Union[STACObject, ItemCollection]:
def read_file(href: str) -> STACObject:
"""Reads a STAC object from a file.
This method will return either a Catalog, a Collection, or an Item based on what the
Expand All @@ -86,15 +86,18 @@ def read_file(href: str) -> Union[STACObject, ItemCollection]:
Returns:
The specific STACObject implementation class that is represented
by the JSON read from the file located at HREF.
Raises:
STACTypeError : If the file at ``href`` does not represent a valid
:class:`~pystac.STACObject`. Note that an :class:`~pystac.ItemCollection` is not
a :class:`~pystac.STACObject` and must be read using
:meth:`ItemCollection.from_file <pystac.ItemCollection.from_file>`
"""
try:
return STACObject.from_file(href)
except STACTypeError:
return ItemCollection.from_file(href)
return STACObject.from_file(href)


def write_file(
obj: Union[STACObject, ItemCollection],
obj: STACObject,
include_self_link: bool = True,
dest_href: Optional[str] = None,
) -> None:
Expand All @@ -113,51 +116,44 @@ def write_file(
Args:
obj : The STACObject to save.
include_self_link : If ``True``, include the ``"self"`` link with this object.
Otherwise, leave out the self link. Ignored for :class:~ItemCollection`
instances.
Otherwise, leave out the self link.
dest_href : Optional HREF to save the file to. If ``None``, the object will be
saved to the object's ``"self"`` href (for :class:`~STACObject` sub-classes)
or a :exc:`~STACError` will be raised (for :class:`~ItemCollection`
instances).
saved to the object's ``"self"`` href.
"""
if isinstance(obj, ItemCollection):
if dest_href is None:
raise STACError("Must provide dest_href when saving and ItemCollection.")
obj.save_object(dest_href=dest_href)
else:
obj.save_object(include_self_link=include_self_link, dest_href=dest_href)
obj.save_object(include_self_link=include_self_link, dest_href=dest_href)


def read_dict(
d: Dict[str, Any],
href: Optional[str] = None,
root: Optional[Catalog] = None,
stac_io: Optional[StacIO] = None,
) -> Union[STACObject, ItemCollection]:
) -> STACObject:
"""Reads a :class:`~STACObject` or :class:`~ItemCollection` from a JSON-like dict
representing a serialized STAC object.
This method will return either a :class:`~Catalog`, :class:`~Collection`,
:class`~Item`, or :class:`~ItemCollection` based on the contents of the dict.
or :class`~Item` based on the contents of the dict.
This is a convenience method for either
:meth:`stac_io.stac_object_from_dict <stac_io.stac_object_from_dict>` or
:meth:`ItemCollection.from_dict <ItemCollection.from_dict>`.
:meth:`stac_io.stac_object_from_dict <stac_io.stac_object_from_dict>`.
Args:
d : The dict to parse.
href : Optional href that is the file location of the object being
parsed. Ignored if the dict represents an :class:`~ItemCollection`.
parsed.
root : Optional root of the catalog for this object.
If provided, the root's resolved object cache can be used to search for
previously resolved instances of the STAC object. Ignored if the dict
represents an :class:`~ItemCollection`.
previously resolved instances of the STAC object.
stac_io: Optional :class:`~StacIO` instance to use for reading. If ``None``,
the default instance will be used.
Raises:
STACTypeError : If the ``d`` dictionary does not represent a valid
:class:`~pystac.STACObject`. Note that an :class:`~pystac.ItemCollection` is not
a :class:`~pystac.STACObject` and must be read using
:meth:`ItemCollection.from_dict <pystac.ItemCollection.from_dict>`
"""
if stac_io is None:
stac_io = StacIO.default()
try:
return stac_io.stac_object_from_dict(d, href, root)
except STACTypeError:
return ItemCollection.from_dict(d)
return stac_io.stac_object_from_dict(d, href, root)
7 changes: 3 additions & 4 deletions tests/data-files/change_stac_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ def migrate(path: str) -> None:
)
)
obj = pystac.read_dict(stac_json, href=path)
if not isinstance(obj, pystac.ItemCollection):
migrated = obj.to_dict(include_self_link=False)
with open(path, "w") as f:
json.dump(migrated, f, indent=2)
migrated = obj.to_dict(include_self_link=False)
with open(path, "w") as f:
json.dump(migrated, f, indent=2)


if __name__ == "__main__":
Expand Down
14 changes: 0 additions & 14 deletions tests/test_item_collection.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
from typing import cast
import unittest
import pystac

Expand Down Expand Up @@ -80,19 +79,6 @@ def test_item_collection_from_dict(self) -> None:
self.assertEqual(expected, len(item_collection.items))
self.assertEqual(item_collection.extra_fields.get("custom_field"), "My value")

def test_item_collection_from_dict_top_level(self) -> None:
features = [item.to_dict() for item in self.items]
d = {
"type": "FeatureCollection",
"features": features,
"custom_field": "My value",
}
item_collection = pystac.read_dict(d)
item_collection = cast(pystac.ItemCollection, item_collection)
expected = len(features)
self.assertEqual(expected, len(item_collection.items))
self.assertEqual(item_collection.extra_fields.get("custom_field"), "My value")

def test_clone_item_collection(self) -> None:
item_collection_1 = pystac.ItemCollection.from_file(self.ITEM_COLLECTION)
item_collection_2 = item_collection_1.clone()
Expand Down
22 changes: 7 additions & 15 deletions tests/test_stac_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,10 @@ def test_read_write_catalog(self) -> None:
pystac.write_file(catalog, dest_href=dest_href)
self.assertTrue(os.path.exists(dest_href), msg="File was not written.")

def test_read_write_item_collection(self) -> None:
item_collection = pystac.read_file(
TestCases.get_path("data-files/item-collection/sample-item-collection.json")
)
with get_temp_dir() as tmp_dir:
dest_href = os.path.join(tmp_dir, "item-collection.json")
pystac.write_file(item_collection, dest_href=dest_href)
self.assertTrue(os.path.exists(dest_href), msg="File was not written.")

def test_write_item_collection_needs_href(self) -> None:
item_collection = pystac.read_file(
TestCases.get_path("data-files/item-collection/sample-item-collection.json")
)
with self.assertRaises(pystac.STACError):
pystac.write_file(item_collection)
def test_read_item_collection_raises_exception(self) -> None:
with self.assertRaises(pystac.STACTypeError):
_ = pystac.read_file(
TestCases.get_path(
"data-files/item-collection/sample-item-collection.json"
)
)
5 changes: 1 addition & 4 deletions tests/validation/test_validate.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import datetime
import json
import os
from typing import Any, Dict, cast
from typing import Any, Dict
from pystac.utils import get_opt
import shutil
import unittest
Expand All @@ -20,7 +20,6 @@ def test_validate_current_version(self) -> None:
catalog = pystac.read_file(
TestCases.get_path("data-files/catalogs/test-case-1/" "catalog.json")
)
catalog = cast(pystac.STACObject, catalog)
catalog.validate()

collection = pystac.read_file(
Expand All @@ -30,11 +29,9 @@ def test_validate_current_version(self) -> None:
"collection.json"
)
)
collection = cast(pystac.Collection, collection)
collection.validate()

item = pystac.read_file(TestCases.get_path("data-files/item/sample-item.json"))
item = cast(pystac.Item, item)
item.validate()

def test_validate_examples(self) -> None:
Expand Down

0 comments on commit 2bb16a1

Please sign in to comment.