pystac-ext-table 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
File without changes
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"""Implements the :stac-ext:`Table Extension <table>`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
from typing import Any, Generic, Literal, TypeVar, cast
|
|
7
|
+
|
|
8
|
+
import pystac
|
|
9
|
+
from pystac.extensions.base import ExtensionManagementMixin, PropertiesExtension
|
|
10
|
+
from pystac.extensions.hooks import ExtensionHooks
|
|
11
|
+
from pystac.utils import get_required
|
|
12
|
+
|
|
13
|
+
#: Generalized version of :class:`~pystac.Collection`, :class:`~pystac.Item`,
|
|
14
|
+
#: :class:`~pystac.Asset` or :class:`~pystac.ItemAssetDefinition`
|
|
15
|
+
T = TypeVar(
|
|
16
|
+
"T", pystac.Collection, pystac.Item, pystac.Asset, pystac.ItemAssetDefinition
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
SCHEMA_URI = "https://stac-extensions.github.io/table/v1.2.0/schema.json"
|
|
20
|
+
|
|
21
|
+
PREFIX: str = "table:"
|
|
22
|
+
COLUMNS_PROP = PREFIX + "columns"
|
|
23
|
+
PRIMARY_GEOMETRY_PROP = PREFIX + "primary_geometry"
|
|
24
|
+
ROW_COUNT_PROP = PREFIX + "row_count"
|
|
25
|
+
STORAGE_OPTIONS_PROP = PREFIX + "storage_options"
|
|
26
|
+
TABLES_PROP = PREFIX + "tables"
|
|
27
|
+
|
|
28
|
+
# Column properties
|
|
29
|
+
COL_NAME_PROP = "name"
|
|
30
|
+
COL_DESCRIPTION_PROP = "description"
|
|
31
|
+
COL_TYPE_PROP = "type"
|
|
32
|
+
|
|
33
|
+
# Table properties
|
|
34
|
+
TBL_NAME_PROP = "name"
|
|
35
|
+
TBL_DESCRIPTION_PROP = "description"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Column:
|
|
39
|
+
"""Object representing a column of a table."""
|
|
40
|
+
|
|
41
|
+
properties: dict[str, Any]
|
|
42
|
+
|
|
43
|
+
def __init__(self, properties: dict[str, Any]):
|
|
44
|
+
self.properties = properties
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def name(self) -> str:
|
|
48
|
+
"""The column name"""
|
|
49
|
+
return cast(
|
|
50
|
+
str,
|
|
51
|
+
get_required(
|
|
52
|
+
self.properties.get(COL_NAME_PROP), "table:column", COL_NAME_PROP
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
@name.setter
|
|
57
|
+
def name(self, v: str) -> None:
|
|
58
|
+
self.properties[COL_NAME_PROP] = v
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def description(self) -> str | None:
|
|
62
|
+
"""Detailed multi-line description to explain the column. `CommonMark 0.29
|
|
63
|
+
<http://commonmark.org/>`__ syntax MAY be used for rich text representation."""
|
|
64
|
+
return self.properties.get(COL_DESCRIPTION_PROP)
|
|
65
|
+
|
|
66
|
+
@description.setter
|
|
67
|
+
def description(self, v: str | None) -> None:
|
|
68
|
+
if v is None:
|
|
69
|
+
self.properties.pop(COL_DESCRIPTION_PROP, None)
|
|
70
|
+
else:
|
|
71
|
+
self.properties[COL_DESCRIPTION_PROP] = v
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def col_type(self) -> str | None:
|
|
75
|
+
"""Data type of the column. If using a file format with a type system (like
|
|
76
|
+
Parquet), we recommend you use those types"""
|
|
77
|
+
return self.properties.get(COL_TYPE_PROP)
|
|
78
|
+
|
|
79
|
+
@col_type.setter
|
|
80
|
+
def col_type(self, v: str | None) -> None:
|
|
81
|
+
if v is None:
|
|
82
|
+
self.properties.pop(COL_TYPE_PROP, None)
|
|
83
|
+
else:
|
|
84
|
+
self.properties[COL_TYPE_PROP] = v
|
|
85
|
+
|
|
86
|
+
def to_dict(self) -> dict[str, Any]:
|
|
87
|
+
"""Returns a dictionary representing this ``Column``."""
|
|
88
|
+
return self.properties
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class Table:
|
|
92
|
+
"""Object containing a high-level summary about a table"""
|
|
93
|
+
|
|
94
|
+
properties: dict[str, Any]
|
|
95
|
+
|
|
96
|
+
def __init__(self, properties: dict[str, Any]):
|
|
97
|
+
self.properties = properties
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def name(self) -> str:
|
|
101
|
+
"""The table name"""
|
|
102
|
+
return cast(
|
|
103
|
+
str, get_required(self.properties.get(TBL_NAME_PROP), self, TBL_NAME_PROP)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
@name.setter
|
|
107
|
+
def name(self, v: str) -> None:
|
|
108
|
+
self.properties[COL_NAME_PROP] = v
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def description(self) -> str | None:
|
|
112
|
+
"""Detailed multi-line description to explain the table. `CommonMark 0.29
|
|
113
|
+
<http://commonmark.org/>`__ syntax MAY be used for rich text representation."""
|
|
114
|
+
return self.properties.get(COL_DESCRIPTION_PROP)
|
|
115
|
+
|
|
116
|
+
@description.setter
|
|
117
|
+
def description(self, v: str | None) -> None:
|
|
118
|
+
if v is None:
|
|
119
|
+
self.properties.pop(COL_DESCRIPTION_PROP, None)
|
|
120
|
+
else:
|
|
121
|
+
self.properties[COL_DESCRIPTION_PROP] = v
|
|
122
|
+
|
|
123
|
+
def to_dict(self) -> dict[str, Any]:
|
|
124
|
+
"""Returns a dictionary representing this ``Table``."""
|
|
125
|
+
return self.properties
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class TableExtension(
|
|
129
|
+
Generic[T],
|
|
130
|
+
PropertiesExtension,
|
|
131
|
+
ExtensionManagementMixin[pystac.Item | pystac.Collection],
|
|
132
|
+
):
|
|
133
|
+
"""An abstract class that can be used to extend the properties of a
|
|
134
|
+
:class:`~pystac.Collection`, :class:`~pystac.Item`, or :class:`~pystac.Asset` with
|
|
135
|
+
properties from the :stac-ext:`Datacube Extension <datacube>`. This class is
|
|
136
|
+
generic over the type of STAC Object to be extended (e.g. :class:`~pystac.Item`,
|
|
137
|
+
:class:`~pystac.Asset`).
|
|
138
|
+
|
|
139
|
+
To create a concrete instance of :class:`TableExtension`, use the
|
|
140
|
+
:meth:`TableExtension.ext` method. For example:
|
|
141
|
+
|
|
142
|
+
.. code-block:: python
|
|
143
|
+
|
|
144
|
+
>>> item: pystac.Item = ...
|
|
145
|
+
>>> tbl_ext = TableExtension.ext(item)
|
|
146
|
+
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
name: Literal["table"] = "table"
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def get_schema_uri(cls) -> str:
|
|
153
|
+
return SCHEMA_URI
|
|
154
|
+
|
|
155
|
+
@classmethod
|
|
156
|
+
def ext(cls, obj: T, add_if_missing: bool = False) -> TableExtension[T]:
|
|
157
|
+
"""Extend the given STAC Object with properties from the
|
|
158
|
+
:stac-ext:`Table Extension <table>`.
|
|
159
|
+
|
|
160
|
+
This extension can be applied to instances of :class:`~pystac.Collection`,
|
|
161
|
+
:class:`~pystac.Item` or :class:`~pystac.Asset`.
|
|
162
|
+
|
|
163
|
+
Raises:
|
|
164
|
+
pystac.ExtensionTypeError : If an invalid object type is passed.
|
|
165
|
+
"""
|
|
166
|
+
if isinstance(obj, pystac.Collection):
|
|
167
|
+
cls.ensure_has_extension(obj, add_if_missing)
|
|
168
|
+
return cast(TableExtension[T], CollectionTableExtension(obj))
|
|
169
|
+
if isinstance(obj, pystac.Item):
|
|
170
|
+
cls.ensure_has_extension(obj, add_if_missing)
|
|
171
|
+
return cast(TableExtension[T], ItemTableExtension(obj))
|
|
172
|
+
if isinstance(obj, pystac.Asset):
|
|
173
|
+
cls.ensure_owner_has_extension(obj, add_if_missing)
|
|
174
|
+
return cast(TableExtension[T], AssetTableExtension(obj))
|
|
175
|
+
elif isinstance(obj, pystac.ItemAssetDefinition):
|
|
176
|
+
cls.ensure_owner_has_extension(obj, add_if_missing)
|
|
177
|
+
return cast(TableExtension[T], ItemAssetsTableExtension(obj))
|
|
178
|
+
else:
|
|
179
|
+
raise pystac.ExtensionTypeError(cls._ext_error_message(obj))
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def columns(self) -> list[Column] | None:
|
|
183
|
+
"""A list of :class:`Column` objects describing each column"""
|
|
184
|
+
v = self.properties.get(COLUMNS_PROP)
|
|
185
|
+
if v is None:
|
|
186
|
+
return None
|
|
187
|
+
return [Column(x) for x in v]
|
|
188
|
+
|
|
189
|
+
@columns.setter
|
|
190
|
+
def columns(self, v: list[Column] | None) -> None:
|
|
191
|
+
self._set_property(COLUMNS_PROP, v)
|
|
192
|
+
|
|
193
|
+
@property
|
|
194
|
+
def primary_geometry(self) -> str | None:
|
|
195
|
+
"""The primary geometry column name"""
|
|
196
|
+
return self._get_property(PRIMARY_GEOMETRY_PROP, str)
|
|
197
|
+
|
|
198
|
+
@primary_geometry.setter
|
|
199
|
+
def primary_geometry(self, v: str | None) -> None:
|
|
200
|
+
if v is None:
|
|
201
|
+
self.properties.pop(PRIMARY_GEOMETRY_PROP, None)
|
|
202
|
+
else:
|
|
203
|
+
self.properties[PRIMARY_GEOMETRY_PROP] = v
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def row_count(self) -> int | None:
|
|
207
|
+
"""The number of rows in the dataset"""
|
|
208
|
+
return self._get_property(ROW_COUNT_PROP, int)
|
|
209
|
+
|
|
210
|
+
@row_count.setter
|
|
211
|
+
def row_count(self, v: int | None) -> None:
|
|
212
|
+
if v is None:
|
|
213
|
+
self.properties.pop(ROW_COUNT_PROP, None)
|
|
214
|
+
else:
|
|
215
|
+
self.properties[ROW_COUNT_PROP] = v
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class CollectionTableExtension(TableExtension[pystac.Collection]):
|
|
219
|
+
"""A concrete implementation of :class:`TableExtension` on a
|
|
220
|
+
:class:`~pystac.Collection` that extends the properties of the Item to include
|
|
221
|
+
properties defined in the :stac-ext:`Table Extension <table>`.
|
|
222
|
+
|
|
223
|
+
This class should generally not be instantiated directly. Instead, call
|
|
224
|
+
:meth:`TableExtension.ext` on an :class:`~pystac.Collection` to extend it.
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
collection: pystac.Collection
|
|
228
|
+
properties: dict[str, Any]
|
|
229
|
+
|
|
230
|
+
def __init__(self, collection: pystac.Collection):
|
|
231
|
+
self.collection = collection
|
|
232
|
+
self.properties = collection.extra_fields
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def tables(self) -> dict[str, Table]:
|
|
236
|
+
"""A mapping of table names to table objects"""
|
|
237
|
+
return get_required(self.properties.get(TABLES_PROP), self, TABLES_PROP)
|
|
238
|
+
|
|
239
|
+
@tables.setter
|
|
240
|
+
def tables(self, v: dict[str, Table]) -> None:
|
|
241
|
+
self.properties[TABLES_PROP] = v
|
|
242
|
+
|
|
243
|
+
def __repr__(self) -> str:
|
|
244
|
+
return f"<CollectionTableExtension Item id={self.collection.id}>"
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class ItemTableExtension(TableExtension[pystac.Item]):
|
|
248
|
+
"""A concrete implementation of :class:`TableExtension` on an
|
|
249
|
+
:class:`~pystac.Item` that extends the properties of the Item to include properties
|
|
250
|
+
defined in the :stac-ext:`Table Extension <table>`.
|
|
251
|
+
|
|
252
|
+
This class should generally not be instantiated directly. Instead, call
|
|
253
|
+
:meth:`TableExtension.ext` on an :class:`~pystac.Item` to extend it.
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
item: pystac.Item
|
|
257
|
+
properties: dict[str, Any]
|
|
258
|
+
|
|
259
|
+
def __init__(self, item: pystac.Item):
|
|
260
|
+
self.item = item
|
|
261
|
+
self.properties = item.properties
|
|
262
|
+
|
|
263
|
+
def __repr__(self) -> str:
|
|
264
|
+
return f"<ItemTableExtension Item id={self.item.id}>"
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class AssetTableExtension(TableExtension[pystac.Asset]):
|
|
268
|
+
"""A concrete implementation of :class:`TableExtension` on an
|
|
269
|
+
:class:`~pystac.Asset` that extends the Asset fields to include properties defined
|
|
270
|
+
in the :stac-ext:`Table Extension <table>`.
|
|
271
|
+
|
|
272
|
+
This class should generally not be instantiated directly. Instead, call
|
|
273
|
+
:meth:`TableExtension.ext` on an :class:`~pystac.Asset` to extend it.
|
|
274
|
+
"""
|
|
275
|
+
|
|
276
|
+
asset_href: str
|
|
277
|
+
properties: dict[str, Any]
|
|
278
|
+
additional_read_properties: Iterable[dict[str, Any]] | None
|
|
279
|
+
|
|
280
|
+
def __init__(self, asset: pystac.Asset):
|
|
281
|
+
self.asset_href = asset.href
|
|
282
|
+
self.properties = asset.extra_fields
|
|
283
|
+
if asset.owner and isinstance(asset.owner, pystac.Item):
|
|
284
|
+
self.additional_read_properties = [asset.owner.properties]
|
|
285
|
+
else:
|
|
286
|
+
self.additional_read_properties = None
|
|
287
|
+
|
|
288
|
+
@property
|
|
289
|
+
def storage_options(self) -> dict[str, Any] | None:
|
|
290
|
+
"""Additional keywords for opening the dataset"""
|
|
291
|
+
return self.properties.get(STORAGE_OPTIONS_PROP)
|
|
292
|
+
|
|
293
|
+
@storage_options.setter
|
|
294
|
+
def storage_options(self, v: dict[str, Any] | None) -> Any:
|
|
295
|
+
if v is None:
|
|
296
|
+
self.properties.pop(STORAGE_OPTIONS_PROP, None)
|
|
297
|
+
else:
|
|
298
|
+
self.properties[STORAGE_OPTIONS_PROP] = v
|
|
299
|
+
|
|
300
|
+
def __repr__(self) -> str:
|
|
301
|
+
return f"<AssetTableExtension Item id={self.asset_href}>"
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
class ItemAssetsTableExtension(TableExtension[pystac.ItemAssetDefinition]):
|
|
305
|
+
properties: dict[str, Any]
|
|
306
|
+
asset_defn: pystac.ItemAssetDefinition
|
|
307
|
+
|
|
308
|
+
def __init__(self, item_asset: pystac.ItemAssetDefinition):
|
|
309
|
+
self.asset_defn = item_asset
|
|
310
|
+
self.properties = item_asset.properties
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class TableExtensinoHooks(ExtensionHooks):
|
|
314
|
+
schema_uri: str = SCHEMA_URI
|
|
315
|
+
prev_extension_ids = {
|
|
316
|
+
"table",
|
|
317
|
+
"https://stac-extensions.github.io/table/v1.0.0/schema.json",
|
|
318
|
+
"https://stac-extensions.github.io/table/v1.0.1/schema.json",
|
|
319
|
+
"https://stac-extensions.github.io/table/v1.1.0/schema.json",
|
|
320
|
+
}
|
|
321
|
+
stac_object_types = {pystac.STACObjectType.COLLECTION, pystac.STACObjectType.ITEM}
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
TABLE_EXTENSION_HOOKS: ExtensionHooks = TableExtensinoHooks()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pystac-ext-table
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: Table extension for PySTAC
|
|
5
|
+
Project-URL: Documentation, https://pystac.readthedocs.io
|
|
6
|
+
Project-URL: Repository, https://github.com/stac-utils/pystac
|
|
7
|
+
Project-URL: Issues, https://github.com/stac-utils/pystac/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/stac-utils/pystac/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Discussions, https://github.com/radiantearth/stac-spec/discussions/categories/stac-software
|
|
10
|
+
License: Apache-2.0
|
|
11
|
+
Keywords: STAC,catalog,imagery,pystac,raster,table
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Natural Language :: English
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: pystac-core
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# pystac-ext-table
|
|
26
|
+
|
|
27
|
+
[PySTAC](https://pypi.org/project/pystac/) extension package for the [Table Extension](https://github.com/stac-extensions/table).
|
|
28
|
+
This extension provides fields for describing tabular data assets, including column definitions, row counts, primary/foreign keys, and storage formats.
|
|
29
|
+
|
|
30
|
+
## Supported versions
|
|
31
|
+
|
|
32
|
+
- [v1.2.0](https://stac-extensions.github.io/table/v1.2.0/schema.json)
|
|
33
|
+
|
|
34
|
+
## Versioning
|
|
35
|
+
|
|
36
|
+
This package's version corresponds to the version of the extension specification it targets.
|
|
37
|
+
When we release updates to the package code without changing the target extension version, we use [post releases](https://packaging.python.org/en/latest/discussions/versioning/#post-releases), e.g. `1.2.0.post1`.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
pystac/extensions/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
pystac/extensions/table.py,sha256=MEamMU8cYTUKFvb4Cm7cY5Pqar71kZYWoZGnCqmevaY,11050
|
|
3
|
+
pystac_ext_table-1.2.0.dist-info/METADATA,sha256=hZ29XA34ml8x7eaoOmDF7OVYM1LJv3Idmx5NPKUoqVM,1807
|
|
4
|
+
pystac_ext_table-1.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
5
|
+
pystac_ext_table-1.2.0.dist-info/RECORD,,
|