Skip to content

Commit 7bf4f6e

Browse files
authored
Update version extension (#1262)
* refactor: normalize import style #1259 * refactor(tests): modernize version extension tests - #993 - #948 * feat: add experimental to version ext * feat: version is optional in version extension * refactor: test import naming, ext * feat: catalog extensions * refactor: import style * feat: add history media type * feat: separate BaseVersionExtension * feat: impl migration * doc: fixups * chore: update changelog * fix(tests): mark some extra vcrs * fix: pop_if_none on deprecated
1 parent 59d1868 commit 7bf4f6e

File tree

40 files changed

+2302
-2994
lines changed

40 files changed

+2302
-2994
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
- `validate_all` now accepts a `STACObject` (in addition to accepting a dict, which is now deprecated), but prohibits supplying a value for `href`, which must be supplied _only_ when supplying an object as a dict. Once `validate_all` removes support for an object as a dict, the `href` parameter will also be removed. ([#1246](https://github.com/stac-utils/pystac/pull/1246))
1414
- Report `href` when schema url resolution fails ([#1263](https://github.com/stac-utils/pystac/pull/1263))
15+
- Version extension updated to v1.2.0 ([#1262](https://github.com/stac-utils/pystac/pull/1262))
1516

1617
### Fixed
1718

pystac/catalog.py

+13
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
if TYPE_CHECKING:
4141
from pystac.asset import Asset
4242
from pystac.collection import Collection
43+
from pystac.extensions.ext import CatalogExt
4344
from pystac.item import Item
4445

4546
C = TypeVar("C", bound="Catalog")
@@ -1245,3 +1246,15 @@ def from_file(cls: type[C], href: HREF, stac_io: pystac.StacIO | None = None) ->
12451246
@classmethod
12461247
def matches_object_type(cls, d: dict[str, Any]) -> bool:
12471248
return identify_stac_object_type(d) == STACObjectType.CATALOG
1249+
1250+
@property
1251+
def ext(self) -> CatalogExt:
1252+
"""Accessor for extension classes on this catalog
1253+
1254+
Example::
1255+
1256+
print(collection.ext.version)
1257+
"""
1258+
from pystac.extensions.ext import CatalogExt
1259+
1260+
return CatalogExt(stac_object=self)

pystac/extensions/ext.py

+43-34
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-
import pystac
4+
from pystac import Asset, Catalog, Collection, Item, STACError
55
from pystac.extensions.classification import ClassificationExtension
66
from pystac.extensions.datacube import DatacubeExtension
77
from pystac.extensions.eo import EOExtension
@@ -18,11 +18,11 @@
1818
from pystac.extensions.storage import StorageExtension
1919
from pystac.extensions.table import TableExtension
2020
from pystac.extensions.timestamps import TimestampsExtension
21-
from pystac.extensions.version import VersionExtension
21+
from pystac.extensions.version import BaseVersionExtension, VersionExtension
2222
from pystac.extensions.view import ViewExtension
2323
from pystac.extensions.xarray_assets import XarrayAssetsExtension
2424

25-
T = TypeVar("T", pystac.Asset, AssetDefinition)
25+
T = TypeVar("T", Asset, AssetDefinition)
2626

2727
EXTENSION_NAMES = Literal[
2828
"classification",
@@ -80,8 +80,8 @@ def _get_class_by_name(name: str) -> Any:
8080

8181

8282
@dataclass
83-
class CollectionExt:
84-
stac_object: pystac.Collection
83+
class CatalogExt:
84+
stac_object: Catalog
8585

8686
def has(self, name: EXTENSION_NAMES) -> bool:
8787
return cast(bool, _get_class_by_name(name).has_extension(self.stac_object))
@@ -93,33 +93,38 @@ def remove(self, name: EXTENSION_NAMES) -> None:
9393
_get_class_by_name(name).remove_from(self.stac_object)
9494

9595
@property
96-
def cube(self) -> DatacubeExtension[pystac.Collection]:
96+
def version(self) -> VersionExtension[Catalog]:
97+
return VersionExtension.ext(self.stac_object)
98+
99+
100+
@dataclass
101+
class CollectionExt(CatalogExt):
102+
stac_object: Collection
103+
104+
@property
105+
def cube(self) -> DatacubeExtension[Collection]:
97106
return DatacubeExtension.ext(self.stac_object)
98107

99108
@property
100109
def item_assets(self) -> dict[str, AssetDefinition]:
101110
return ItemAssetsExtension.ext(self.stac_object).item_assets
102111

103112
@property
104-
def sci(self) -> ScientificExtension[pystac.Collection]:
113+
def sci(self) -> ScientificExtension[Collection]:
105114
return ScientificExtension.ext(self.stac_object)
106115

107116
@property
108-
def table(self) -> TableExtension[pystac.Collection]:
117+
def table(self) -> TableExtension[Collection]:
109118
return TableExtension.ext(self.stac_object)
110119

111120
@property
112-
def version(self) -> VersionExtension[pystac.Collection]:
113-
return VersionExtension.ext(self.stac_object)
114-
115-
@property
116-
def xarray(self) -> XarrayAssetsExtension[pystac.Collection]:
121+
def xarray(self) -> XarrayAssetsExtension[Collection]:
117122
return XarrayAssetsExtension.ext(self.stac_object)
118123

119124

120125
@dataclass
121126
class ItemExt:
122-
stac_object: pystac.Item
127+
stac_object: Item
123128

124129
def has(self, name: EXTENSION_NAMES) -> bool:
125130
return cast(bool, _get_class_by_name(name).has_extension(self.stac_object))
@@ -131,15 +136,15 @@ def remove(self, name: EXTENSION_NAMES) -> None:
131136
_get_class_by_name(name).remove_from(self.stac_object)
132137

133138
@property
134-
def classification(self) -> ClassificationExtension[pystac.Item]:
139+
def classification(self) -> ClassificationExtension[Item]:
135140
return ClassificationExtension.ext(self.stac_object)
136141

137142
@property
138-
def cube(self) -> DatacubeExtension[pystac.Item]:
143+
def cube(self) -> DatacubeExtension[Item]:
139144
return DatacubeExtension.ext(self.stac_object)
140145

141146
@property
142-
def eo(self) -> EOExtension[pystac.Item]:
147+
def eo(self) -> EOExtension[Item]:
143148
return EOExtension.ext(self.stac_object)
144149

145150
@property
@@ -151,43 +156,43 @@ def mgrs(self) -> MgrsExtension:
151156
return MgrsExtension.ext(self.stac_object)
152157

153158
@property
154-
def pc(self) -> PointcloudExtension[pystac.Item]:
159+
def pc(self) -> PointcloudExtension[Item]:
155160
return PointcloudExtension.ext(self.stac_object)
156161

157162
@property
158-
def proj(self) -> ProjectionExtension[pystac.Item]:
163+
def proj(self) -> ProjectionExtension[Item]:
159164
return ProjectionExtension.ext(self.stac_object)
160165

161166
@property
162-
def sar(self) -> SarExtension[pystac.Item]:
167+
def sar(self) -> SarExtension[Item]:
163168
return SarExtension.ext(self.stac_object)
164169

165170
@property
166-
def sat(self) -> SatExtension[pystac.Item]:
171+
def sat(self) -> SatExtension[Item]:
167172
return SatExtension.ext(self.stac_object)
168173

169174
@property
170-
def storage(self) -> StorageExtension[pystac.Item]:
175+
def storage(self) -> StorageExtension[Item]:
171176
return StorageExtension.ext(self.stac_object)
172177

173178
@property
174-
def table(self) -> TableExtension[pystac.Item]:
179+
def table(self) -> TableExtension[Item]:
175180
return TableExtension.ext(self.stac_object)
176181

177182
@property
178-
def timestamps(self) -> TimestampsExtension[pystac.Item]:
183+
def timestamps(self) -> TimestampsExtension[Item]:
179184
return TimestampsExtension.ext(self.stac_object)
180185

181186
@property
182-
def version(self) -> VersionExtension[pystac.Item]:
187+
def version(self) -> VersionExtension[Item]:
183188
return VersionExtension.ext(self.stac_object)
184189

185190
@property
186-
def view(self) -> ViewExtension[pystac.Item]:
191+
def view(self) -> ViewExtension[Item]:
187192
return ViewExtension.ext(self.stac_object)
188193

189194
@property
190-
def xarray(self) -> XarrayAssetsExtension[pystac.Item]:
195+
def xarray(self) -> XarrayAssetsExtension[Item]:
191196
return XarrayAssetsExtension.ext(self.stac_object)
192197

193198

@@ -196,7 +201,7 @@ class _AssetExt(Generic[T]):
196201

197202
def has(self, name: EXTENSION_NAMES) -> bool:
198203
if self.stac_object.owner is None:
199-
raise pystac.STACError(
204+
raise STACError(
200205
f"Attempted to add extension='{name}' for an Asset with no owner. "
201206
"Use Asset.set_owner and then try to add the extension again."
202207
)
@@ -207,7 +212,7 @@ def has(self, name: EXTENSION_NAMES) -> bool:
207212

208213
def add(self, name: EXTENSION_NAMES) -> None:
209214
if self.stac_object.owner is None:
210-
raise pystac.STACError(
215+
raise STACError(
211216
f"Attempted to add extension='{name}' for an Asset with no owner. "
212217
"Use Asset.set_owner and then try to add the extension again."
213218
)
@@ -216,7 +221,7 @@ def add(self, name: EXTENSION_NAMES) -> None:
216221

217222
def remove(self, name: EXTENSION_NAMES) -> None:
218223
if self.stac_object.owner is None:
219-
raise pystac.STACError(
224+
raise STACError(
220225
f"Attempted to remove extension='{name}' for an Asset with no owner. "
221226
"Use Asset.set_owner and then try to remove the extension again."
222227
)
@@ -263,25 +268,29 @@ def storage(self) -> StorageExtension[T]:
263268
def table(self) -> TableExtension[T]:
264269
return TableExtension.ext(self.stac_object)
265270

271+
@property
272+
def version(self) -> BaseVersionExtension[T]:
273+
return BaseVersionExtension.ext(self.stac_object)
274+
266275
@property
267276
def view(self) -> ViewExtension[T]:
268277
return ViewExtension.ext(self.stac_object)
269278

270279

271280
@dataclass
272-
class AssetExt(_AssetExt[pystac.Asset]):
273-
stac_object: pystac.Asset
281+
class AssetExt(_AssetExt[Asset]):
282+
stac_object: Asset
274283

275284
@property
276285
def file(self) -> FileExtension:
277286
return FileExtension.ext(self.stac_object)
278287

279288
@property
280-
def timestamps(self) -> TimestampsExtension[pystac.Asset]:
289+
def timestamps(self) -> TimestampsExtension[Asset]:
281290
return TimestampsExtension.ext(self.stac_object)
282291

283292
@property
284-
def xarray(self) -> XarrayAssetsExtension[pystac.Asset]:
293+
def xarray(self) -> XarrayAssetsExtension[Asset]:
285294
return XarrayAssetsExtension.ext(self.stac_object)
286295

287296

0 commit comments

Comments
 (0)