Skip to content

Commit

Permalink
Store file:values as list of dicts in Item properties (#700)
Browse files Browse the repository at this point in the history
* Store file:values as list of dicts in Item properties

* Add CHANGELOG entry for #700
  • Loading branch information
Jon Duckworth authored Jan 14, 2022
1 parent 03d577c commit 5cff27d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

- Quickstart tutorial is now up-to-date with all package changes ([#674](https://github.com/stac-utils/pystac/pull/674))
- Creating absolute URLs from absolute URLs ([#697](https://github.com/stac-utils/pystac/pull/697)])
- Serialization error when using `pystac.extensions.file.MappingObject` ([#700](https://github.com/stac-utils/pystac/pull/700))

### Deprecated

Expand Down
23 changes: 20 additions & 3 deletions pystac/extensions/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
STACJSONDescription,
STACVersionID,
)
from pystac.utils import StringEnum, get_required
from pystac.utils import StringEnum, get_required, map_opt

SCHEMA_URI = "https://stac-extensions.github.io/file/v2.0.0/schema.json"

Expand Down Expand Up @@ -83,6 +83,13 @@ def summary(self) -> str:
def summary(self, v: str) -> None:
self.properties["summary"] = v

@classmethod
def from_dict(cls, d: Dict[str, Any]) -> "MappingObject":
return cls.create(**d)

def to_dict(self) -> Dict[str, Any]:
return self.properties


class FileExtension(
PropertiesExtension, ExtensionManagementMixin[Union[pystac.Item, pystac.Collection]]
Expand Down Expand Up @@ -180,11 +187,21 @@ def values(self) -> Optional[List[MappingObject]]:
values that are in the file and describe their meaning. See the
:stac-ext:`Mapping Object <file#mapping-object>` docs for an example. If given,
at least one array element is required."""
return self._get_property(VALUES_PROP, List[MappingObject])
return map_opt(
lambda values: [
MappingObject.from_dict(mapping_obj) for mapping_obj in values
],
self._get_property(VALUES_PROP, List[Dict[str, Any]]),
)

@values.setter
def values(self, v: Optional[List[MappingObject]]) -> None:
self._set_property(VALUES_PROP, v)
self._set_property(
VALUES_PROP,
map_opt(
lambda values: [mapping_obj.to_dict() for mapping_obj in values], v
),
)

@classmethod
def get_schema_uri(cls) -> str:
Expand Down
25 changes: 16 additions & 9 deletions tests/extensions/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,17 @@ def test_item_asset_values(self) -> None:
item = pystac.Item.from_file(self.FILE_ITEM_EXAMPLE_URI)
asset = item.assets["thumbnail"]
file_ext = FileExtension.ext(asset)
values = [MappingObject.create([0], summary="clouds")]
mapping_obj = {"values": [0], "summary": "clouds"}

file_ext.values = values
# file_ext.values = values
file_ext.apply(values=[MappingObject.from_dict(mapping_obj)])

self.assertEqual(file_ext.values, values)
self.assertListEqual(asset.extra_fields["file:values"], [mapping_obj])

values_field = asset.extra_fields["file:values"]
self.assertIsInstance(values_field, list)
for mapping_obj in values_field:
self.assertIsInstance(mapping_obj, dict)

def test_item_asset_apply(self) -> None:
item = pystac.Item.from_file(self.FILE_ITEM_EXAMPLE_URI)
Expand All @@ -146,7 +152,8 @@ def test_item_asset_apply(self) -> None:
new_checksum = "90e40210163700a8a6501eccd00b6d3b44ddaed0"
new_size = 1
new_header_size = 8192
new_values = [MappingObject.create([0], summary="clouds")]
new_mapping_obj = {"values": [0], "summary": "clouds"}
new_values = [MappingObject.from_dict(new_mapping_obj)]
new_byte_order = ByteOrder.LITTLE_ENDIAN

self.assertNotEqual(file_ext.checksum, new_checksum)
Expand All @@ -163,11 +170,11 @@ def test_item_asset_apply(self) -> None:
values=new_values,
)

self.assertEqual(file_ext.checksum, new_checksum)
self.assertEqual(file_ext.size, new_size)
self.assertEqual(file_ext.header_size, new_header_size)
self.assertEqual(file_ext.values, new_values)
self.assertEqual(file_ext.byte_order, new_byte_order)
self.assertEqual(asset.extra_fields["file:checksum"], new_checksum)
self.assertEqual(asset.extra_fields["file:size"], new_size)
self.assertEqual(asset.extra_fields["file:header_size"], new_header_size)
self.assertEqual(asset.extra_fields["file:values"], [new_mapping_obj])
self.assertEqual(asset.extra_fields["file:byte_order"], new_byte_order)

def test_repr(self) -> None:
item = pystac.Item.from_file(self.FILE_ITEM_EXAMPLE_URI)
Expand Down

0 comments on commit 5cff27d

Please sign in to comment.