Skip to content

Commit 85eab26

Browse files
author
Ariana Barzinpour
committed
handle missing _md product attr; update use of DatasetType
1 parent e7aa2e4 commit 85eab26

File tree

3 files changed

+28
-12
lines changed

3 files changed

+28
-12
lines changed

docs/stac-vs-odc.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ similar concepts.
1313
- ODC
1414
- Description
1515
* - :py:class:`~pystac.Collection`
16-
- Product or :py:class:`~datacube.model.DatasetType`
16+
- :py:class:`~datacube.model.Product`
1717
- Collection of observations across space and time
1818
* - :py:class:`~pystac.Item`
1919
- :py:class:`~datacube.model.Dataset`

odc/stac/eo3/_eo3converter.py

+15-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
except ImportError:
2121
from datacube.index.abstract import default_metadata_type_docs # type: ignore
2222

23-
from datacube.model import Dataset, DatasetType, metadata_from_doc
23+
from datacube.model import Dataset, Product, metadata_from_doc
2424
from odc.geo import CRS
2525
from odc.geo.geobox import GeoBox
2626
from toolz import dicttoolz
@@ -60,7 +60,7 @@
6060
)
6161

6262

63-
def _to_product(md: RasterCollectionMetadata) -> DatasetType:
63+
def _to_product(md: RasterCollectionMetadata) -> Product:
6464
def make_band(
6565
band_key: BandKey,
6666
band: RasterBandMetadata,
@@ -95,11 +95,11 @@ def make_band(
9595
for band_key, band in md.meta.bands.items()
9696
],
9797
}
98-
return DatasetType(_eo3, doc)
98+
return Product(_eo3, doc)
9999

100100

101101
@singledispatch
102-
def infer_dc_product(x: Any, cfg: Optional[ConversionConfig] = None) -> DatasetType:
102+
def infer_dc_product(x: Any, cfg: Optional[ConversionConfig] = None) -> Product:
103103
"""Overloaded function."""
104104
raise TypeError(
105105
"Invalid type, must be one of: pystac.item.Item, pystac.collection.Collection"
@@ -109,7 +109,7 @@ def infer_dc_product(x: Any, cfg: Optional[ConversionConfig] = None) -> DatasetT
109109
@infer_dc_product.register(pystac.item.Item)
110110
def infer_dc_product_from_item(
111111
item: pystac.item.Item, cfg: Optional[ConversionConfig] = None
112-
) -> DatasetType:
112+
) -> Product:
113113
"""
114114
Infer Datacube product object from a STAC Item.
115115
@@ -164,7 +164,7 @@ def _to_dataset(
164164
item: ParsedItem,
165165
properties: Dict[str, Any],
166166
ds_uuid: uuid.UUID,
167-
product: DatasetType,
167+
product: Product,
168168
) -> Dataset:
169169
# pylint: disable=too-many-locals
170170

@@ -227,7 +227,7 @@ def _to_dataset(
227227

228228

229229
def _item_to_ds(
230-
item: pystac.item.Item, product: DatasetType, cfg: Optional[ConversionConfig] = None
230+
item: pystac.item.Item, product: Product, cfg: Optional[ConversionConfig] = None
231231
) -> Dataset:
232232
"""
233233
Construct Dataset object from STAC Item and previously constructed Product.
@@ -251,7 +251,7 @@ def _item_to_ds(
251251
def stac2ds(
252252
items: Iterable[pystac.item.Item],
253253
cfg: Optional[ConversionConfig] = None,
254-
product_cache: Optional[Dict[str, DatasetType]] = None,
254+
product_cache: Optional[Dict[str, Product]] = None,
255255
) -> Iterator[Dataset]:
256256
"""
257257
STAC :class:`~pystac.item.Item` to :class:`~datacube.model.Dataset` stream converter.
@@ -276,7 +276,7 @@ def stac2ds(
276276
277277
:param product_cache:
278278
Input/Output parameter, contains mapping from collection name to deduced product definition,
279-
i.e. :py:class:`datacube.model.DatasetType` object.
279+
i.e. :py:class:`datacube.model.Product` object.
280280
281281
.. rubric: Sample Configuration
282282
@@ -312,7 +312,7 @@ def stac2ds(
312312
warnings: ignore
313313
314314
"""
315-
products: Dict[str, DatasetType] = {} if product_cache is None else product_cache
315+
products: Dict[str, Product] = {} if product_cache is None else product_cache
316316
for item in items:
317317
collection_id = _collection_id(item)
318318
product = products.get(collection_id)
@@ -321,14 +321,18 @@ def stac2ds(
321321
if product is None:
322322
product = infer_dc_product(item, cfg)
323323
products[collection_id] = product
324+
# if product_cache was provided, the products within may not have the custom _md attr
325+
if not hasattr(product, "_md"): # pylint: disable=protected-access
326+
md = extract_collection_metadata(item, cfg)
327+
setattr(product, "_md", md) # pylint: disable=protected-access
324328

325329
yield _item_to_ds(item, product, cfg)
326330

327331

328332
@infer_dc_product.register(pystac.collection.Collection)
329333
def infer_dc_product_from_collection(
330334
collection: pystac.collection.Collection, cfg: Optional[ConversionConfig] = None
331-
) -> DatasetType:
335+
) -> Product:
332336
"""
333337
Construct Datacube Product definition from STAC Collection.
334338

tests/test_eo3converter.py

+12
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,15 @@ def test_old_imports():
234234

235235
with pytest.raises(AttributeError):
236236
_ = odc.stac.no_such_thing
237+
238+
239+
def test_product_cache(sentinel_stac_ms: pystac.item.Item):
240+
item = sentinel_stac_ms
241+
# simulate a product that was not created via infer_dc_product
242+
# (and therefore did not have the _md attr set)
243+
product = infer_dc_product(item, STAC_CFG)
244+
delattr(product, "_md")
245+
246+
# make sure it doesn't error when product_cache is provided
247+
(ds,) = stac2ds([item], STAC_CFG, {product.name: product})
248+
assert ds.id

0 commit comments

Comments
 (0)