Skip to content

Commit d7a6712

Browse files
jsignellgadomski
andauthored
Update file extension and add Link.ext (#1265)
* Update file extension, add Link.ext, let file apply to catalogs * Recreate all cassettes for test_file * Missed some cassettes * Let objects use v1.0.0 of file ext, but warn them if old fields present * Align with #1264 and #1258 --------- Co-authored-by: Pete Gadomski <pete.gadomski@gmail.com>
1 parent ed81036 commit d7a6712

37 files changed

+2098
-666
lines changed

pystac/extensions/base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ def validate_owner_has_extension(
190190
@classmethod
191191
def ensure_owner_has_extension(
192192
cls,
193-
asset: pystac.Asset | AssetDefinition,
193+
asset_or_link: pystac.Asset | AssetDefinition | pystac.Link,
194194
add_if_missing: bool = False,
195195
) -> None:
196196
"""Given an :class:`~pystac.Asset`, checks if the asset's owner has this
@@ -206,15 +206,15 @@ def ensure_owner_has_extension(
206206
STACError : If ``add_if_missing`` is ``True`` and ``asset.owner`` is
207207
``None``.
208208
"""
209-
if asset.owner is None:
209+
if asset_or_link.owner is None:
210210
if add_if_missing:
211211
raise pystac.STACError(
212-
"Attempted to use add_if_missing=True for an Asset or ItemAsset "
212+
f"Attempted to use add_if_missing=True for a {type(asset_or_link)} "
213213
"with no owner. Use .set_owner or set add_if_missing=False."
214214
)
215215
else:
216216
return
217-
return cls.ensure_has_extension(cast(S, asset.owner), add_if_missing)
217+
return cls.ensure_has_extension(cast(S, asset_or_link.owner), add_if_missing)
218218

219219
@classmethod
220220
def validate_has_extension(cls, obj: S, add_if_missing: bool = False) -> None:

pystac/extensions/ext.py

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from dataclasses import dataclass
22
from typing import Any, Generic, Literal, TypeVar, cast
33

4-
from pystac import Asset, Catalog, Collection, Item, STACError
4+
from pystac import Asset, Catalog, Collection, Item, Link, STACError
55
from pystac.extensions.classification import ClassificationExtension
66
from pystac.extensions.datacube import DatacubeExtension
77
from pystac.extensions.eo import EOExtension
@@ -22,7 +22,8 @@
2222
from pystac.extensions.view import ViewExtension
2323
from pystac.extensions.xarray_assets import XarrayAssetsExtension
2424

25-
T = TypeVar("T", Asset, AssetDefinition)
25+
T = TypeVar("T", Asset, AssetDefinition, Link)
26+
U = TypeVar("U", Asset, AssetDefinition)
2627

2728
EXTENSION_NAMES = Literal[
2829
"classification",
@@ -196,14 +197,14 @@ def xarray(self) -> XarrayAssetsExtension[Item]:
196197
return XarrayAssetsExtension.ext(self.stac_object)
197198

198199

199-
class _AssetExt(Generic[T]):
200+
class _AssetsExt(Generic[T]):
200201
stac_object: T
201202

202203
def has(self, name: EXTENSION_NAMES) -> bool:
203204
if self.stac_object.owner is None:
204205
raise STACError(
205-
f"Attempted to add extension='{name}' for an Asset with no owner. "
206-
"Use Asset.set_owner and then try to add the extension again."
206+
f"Attempted to add extension='{name}' for an object with no owner. "
207+
"Use `.set_owner` and then try to add the extension again."
207208
)
208209
else:
209210
return cast(
@@ -213,67 +214,71 @@ def has(self, name: EXTENSION_NAMES) -> bool:
213214
def add(self, name: EXTENSION_NAMES) -> None:
214215
if self.stac_object.owner is None:
215216
raise STACError(
216-
f"Attempted to add extension='{name}' for an Asset with no owner. "
217-
"Use Asset.set_owner and then try to add the extension again."
217+
f"Attempted to add extension='{name}' for an object with no owner. "
218+
"Use `.set_owner` and then try to add the extension again."
218219
)
219220
else:
220221
_get_class_by_name(name).add_to(self.stac_object.owner)
221222

222223
def remove(self, name: EXTENSION_NAMES) -> None:
223224
if self.stac_object.owner is None:
224225
raise STACError(
225-
f"Attempted to remove extension='{name}' for an Asset with no owner. "
226-
"Use Asset.set_owner and then try to remove the extension again."
226+
f"Attempted to remove extension='{name}' for an object with no owner. "
227+
"Use `.set_owner` and then try to remove the extension again."
227228
)
228229
else:
229230
_get_class_by_name(name).remove_from(self.stac_object.owner)
230231

232+
233+
class _AssetExt(_AssetsExt[U]):
234+
stac_object: U
235+
231236
@property
232-
def classification(self) -> ClassificationExtension[T]:
237+
def classification(self) -> ClassificationExtension[U]:
233238
return ClassificationExtension.ext(self.stac_object)
234239

235240
@property
236-
def cube(self) -> DatacubeExtension[T]:
241+
def cube(self) -> DatacubeExtension[U]:
237242
return DatacubeExtension.ext(self.stac_object)
238243

239244
@property
240-
def eo(self) -> EOExtension[T]:
245+
def eo(self) -> EOExtension[U]:
241246
return EOExtension.ext(self.stac_object)
242247

243248
@property
244-
def pc(self) -> PointcloudExtension[T]:
249+
def pc(self) -> PointcloudExtension[U]:
245250
return PointcloudExtension.ext(self.stac_object)
246251

247252
@property
248-
def proj(self) -> ProjectionExtension[T]:
253+
def proj(self) -> ProjectionExtension[U]:
249254
return ProjectionExtension.ext(self.stac_object)
250255

251256
@property
252-
def raster(self) -> RasterExtension[T]:
257+
def raster(self) -> RasterExtension[U]:
253258
return RasterExtension.ext(self.stac_object)
254259

255260
@property
256-
def sar(self) -> SarExtension[T]:
261+
def sar(self) -> SarExtension[U]:
257262
return SarExtension.ext(self.stac_object)
258263

259264
@property
260-
def sat(self) -> SatExtension[T]:
265+
def sat(self) -> SatExtension[U]:
261266
return SatExtension.ext(self.stac_object)
262267

263268
@property
264-
def storage(self) -> StorageExtension[T]:
269+
def storage(self) -> StorageExtension[U]:
265270
return StorageExtension.ext(self.stac_object)
266271

267272
@property
268-
def table(self) -> TableExtension[T]:
273+
def table(self) -> TableExtension[U]:
269274
return TableExtension.ext(self.stac_object)
270275

271276
@property
272-
def version(self) -> BaseVersionExtension[T]:
277+
def version(self) -> BaseVersionExtension[U]:
273278
return BaseVersionExtension.ext(self.stac_object)
274279

275280
@property
276-
def view(self) -> ViewExtension[T]:
281+
def view(self) -> ViewExtension[U]:
277282
return ViewExtension.ext(self.stac_object)
278283

279284

@@ -282,7 +287,7 @@ class AssetExt(_AssetExt[Asset]):
282287
stac_object: Asset
283288

284289
@property
285-
def file(self) -> FileExtension:
290+
def file(self) -> FileExtension[Asset]:
286291
return FileExtension.ext(self.stac_object)
287292

288293
@property
@@ -297,3 +302,12 @@ def xarray(self) -> XarrayAssetsExtension[Asset]:
297302
@dataclass
298303
class ItemAssetExt(_AssetExt[AssetDefinition]):
299304
stac_object: AssetDefinition
305+
306+
307+
@dataclass
308+
class LinkExt(_AssetsExt[Link]):
309+
stac_object: Link
310+
311+
@property
312+
def file(self) -> FileExtension[Link]:
313+
return FileExtension.ext(self.stac_object)

0 commit comments

Comments
 (0)