Skip to content

Commit 7b1441e

Browse files
Ariana-BAriana Barzinpour
and
Ariana Barzinpour
authored
Don't assume product._md exists (#171)
* handle missing _md product attr; update use of DatasetType * lower bound datacube version --------- Co-authored-by: Ariana Barzinpour <[email protected]>
1 parent 696c171 commit 7b1441e

File tree

4 files changed

+25
-14
lines changed

4 files changed

+25
-14
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

+12-12
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

@@ -228,7 +228,7 @@ def _to_dataset(
228228

229229

230230
def _item_to_ds(
231-
item: pystac.item.Item, product: DatasetType, cfg: Optional[ConversionConfig] = None
231+
item: pystac.item.Item, product: Product, cfg: Optional[ConversionConfig] = None
232232
) -> Dataset:
233233
"""
234234
Construct Dataset object from STAC Item and previously constructed Product.
@@ -239,7 +239,7 @@ def _item_to_ds(
239239
if cfg is None:
240240
cfg = {}
241241

242-
md: RasterCollectionMetadata = getattr(product, "_md")
242+
md: Optional[RasterCollectionMetadata] = getattr(product, "_md", None)
243243
uuid_cfg = cfg.get("uuid", {})
244244
ds_uuid = _compute_uuid(
245245
item, mode=uuid_cfg.get("mode", "auto"), extras=uuid_cfg.get("extras", [])
@@ -252,7 +252,7 @@ def _item_to_ds(
252252
def stac2ds(
253253
items: Iterable[pystac.item.Item],
254254
cfg: Optional[ConversionConfig] = None,
255-
product_cache: Optional[Dict[str, DatasetType]] = None,
255+
product_cache: Optional[Dict[str, Product]] = None,
256256
) -> Iterator[Dataset]:
257257
"""
258258
STAC :class:`~pystac.item.Item` to :class:`~datacube.model.Dataset` stream converter.
@@ -277,7 +277,7 @@ def stac2ds(
277277
278278
:param product_cache:
279279
Input/Output parameter, contains mapping from collection name to deduced product definition,
280-
i.e. :py:class:`datacube.model.DatasetType` object.
280+
i.e. :py:class:`datacube.model.Product` object.
281281
282282
.. rubric: Sample Configuration
283283
@@ -313,7 +313,7 @@ def stac2ds(
313313
warnings: ignore
314314
315315
"""
316-
products: Dict[str, DatasetType] = {} if product_cache is None else product_cache
316+
products: Dict[str, Product] = {} if product_cache is None else product_cache
317317
for item in items:
318318
collection_id = _collection_id(item)
319319
product = products.get(collection_id)
@@ -329,7 +329,7 @@ def stac2ds(
329329
@infer_dc_product.register(pystac.collection.Collection)
330330
def infer_dc_product_from_collection(
331331
collection: pystac.collection.Collection, cfg: Optional[ConversionConfig] = None
332-
) -> DatasetType:
332+
) -> Product:
333333
"""
334334
Construct Datacube Product definition from STAC Collection.
335335

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ docs =
5858
matplotlib-inline
5959
pandas
6060
distributed
61-
datacube
61+
datacube>=1.8.8
6262
ipython
6363
ipykernel
6464

tests/test_eo3converter.py

+11
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,14 @@ 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+
# make sure it doesn't error when product_cache is provided
246+
(ds,) = stac2ds([item], STAC_CFG, {product.name: product})
247+
assert ds.id

0 commit comments

Comments
 (0)