pystac-ext-xarray-assets 1.0.0__tar.gz

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.
@@ -0,0 +1,163 @@
1
+ *.pyc
2
+ *.egg-info
3
+ *.eggs
4
+ .DS_Store
5
+ data
6
+ config.json
7
+ stdout*
8
+ /integration*
9
+ .idea
10
+ .vscode
11
+ .actrc
12
+
13
+
14
+ # Sphinx documentation
15
+ .ipynb_checkpoints/
16
+
17
+ docs/tutorials/pystac-example*
18
+ docs/tutorials/spacenet-stac/
19
+ docs/tutorials/spacenet-cog-stac/
20
+ docs/tutorials/data/
21
+ docs/quickstart_stac/
22
+
23
+ # Byte-compiled / optimized / DLL files
24
+ __pycache__/
25
+ *.py[cod]
26
+ *$py.class
27
+
28
+ # C extensions
29
+ *.so
30
+
31
+ # Distribution / packaging
32
+ .Python
33
+ build/
34
+ develop-eggs/
35
+ dist/
36
+ downloads/
37
+ eggs/
38
+ .eggs/
39
+ lib/
40
+ lib64/
41
+ parts/
42
+ sdist/
43
+ var/
44
+ wheels/
45
+ share/python-wheels/
46
+ *.egg-info/
47
+ .installed.cfg
48
+ *.egg
49
+ MANIFEST
50
+
51
+ # PyInstaller
52
+ # Usually these files are written by a python script from a template
53
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
54
+ *.manifest
55
+ *.spec
56
+
57
+ # Installer logs
58
+ pip-log.txt
59
+ pip-delete-this-directory.txt
60
+
61
+ # Unit test / coverage reports
62
+ htmlcov/
63
+ .tox/
64
+ .nox/
65
+ .coverage
66
+ .coverage.*
67
+ .cache
68
+ nosetests.xml
69
+ coverage.xml
70
+ *.cover
71
+ *.py,cover
72
+ .hypothesis/
73
+ .pytest_cache/
74
+ cover/
75
+
76
+ # Translations
77
+ *.mo
78
+ *.pot
79
+
80
+ # Django stuff:
81
+ *.log
82
+ local_settings.py
83
+ db.sqlite3
84
+ db.sqlite3-journal
85
+
86
+ # Flask stuff:
87
+ instance/
88
+ .webassets-cache
89
+
90
+ # Scrapy stuff:
91
+ .scrapy
92
+
93
+ # Sphinx documentation
94
+ docs/_build/
95
+
96
+ # PyBuilder
97
+ .pybuilder/
98
+ target/
99
+
100
+ # Jupyter Notebook
101
+ .ipynb_checkpoints
102
+
103
+ # IPython
104
+ profile_default/
105
+ ipython_config.py
106
+
107
+ # pyenv
108
+ # For a library or package, you might want to ignore these files since the code is
109
+ # intended to run in multiple environments; otherwise, check them in:
110
+ # .python-version
111
+
112
+ # pipenv
113
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
114
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
115
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
116
+ # install all needed dependencies.
117
+ # Pipfile.lock
118
+
119
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
120
+ __pypackages__/
121
+
122
+ # Celery stuff
123
+ celerybeat-schedule
124
+ celerybeat.pid
125
+
126
+ # SageMath parsed files
127
+ *.sage.py
128
+
129
+ # Environments
130
+ .env
131
+ .venv
132
+ env/
133
+ venv/
134
+ ENV/
135
+ env.bak/
136
+ venv.bak/
137
+
138
+ # Spyder project settings
139
+ .spyderproject
140
+ .spyproject
141
+
142
+ # Rope project settings
143
+ .ropeproject
144
+
145
+ # mkdocs documentation
146
+ /site
147
+
148
+ # mypy
149
+ .mypy_cache/
150
+ .dmypy.json
151
+ dmypy.json
152
+
153
+ # Pyre type checker
154
+ .pyre/
155
+
156
+ # pytype static type analyzer
157
+ .pytype/
158
+
159
+ # Cython debug symbols
160
+ cython_debug/
161
+
162
+ # asv environments
163
+ .asv
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.4
2
+ Name: pystac-ext-xarray-assets
3
+ Version: 1.0.0
4
+ Summary: Xarray Assets 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,xarray-assets
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-xarray-assets
26
+
27
+ [PySTAC](https://pypi.org/project/pystac/) extension package for the [Xarray Assets Extension](https://github.com/stac-extensions/xarray-assets).
28
+ This extension provides fields for describing how assets can be opened with [xarray](https://xarray.dev/), including storage options, open parameters, and engine configuration.
29
+
30
+ ## Supported versions
31
+
32
+ - [v1.0.0](https://stac-extensions.github.io/xarray-assets/v1.0.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.0.0.post1`.
@@ -0,0 +1,13 @@
1
+ # pystac-ext-xarray-assets
2
+
3
+ [PySTAC](https://pypi.org/project/pystac/) extension package for the [Xarray Assets Extension](https://github.com/stac-extensions/xarray-assets).
4
+ This extension provides fields for describing how assets can be opened with [xarray](https://xarray.dev/), including storage options, open parameters, and engine configuration.
5
+
6
+ ## Supported versions
7
+
8
+ - [v1.0.0](https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json)
9
+
10
+ ## Versioning
11
+
12
+ This package's version corresponds to the version of the extension specification it targets.
13
+ 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.0.0.post1`.
@@ -0,0 +1,36 @@
1
+ [project]
2
+ name = "pystac-ext-xarray-assets"
3
+ description = "Xarray Assets extension for PySTAC"
4
+ readme = "README.md"
5
+ version = "1.0.0"
6
+ authors = []
7
+ maintainers = []
8
+ keywords = ["pystac", "imagery", "raster", "catalog", "STAC", "xarray-assets"]
9
+ license = { text = "Apache-2.0" }
10
+ classifiers = [
11
+ "Development Status :: 5 - Production/Stable",
12
+ "Intended Audience :: Developers",
13
+ "License :: OSI Approved :: Apache Software License",
14
+ "Natural Language :: English",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ ]
21
+ requires-python = ">=3.10"
22
+ dependencies = ["pystac-core"]
23
+
24
+ [project.urls]
25
+ Documentation = "https://pystac.readthedocs.io"
26
+ Repository = "https://github.com/stac-utils/pystac"
27
+ Issues = "https://github.com/stac-utils/pystac/issues"
28
+ Changelog = "https://github.com/stac-utils/pystac/blob/main/CHANGELOG.md"
29
+ Discussions = "https://github.com/radiantearth/stac-spec/discussions/categories/stac-software"
30
+
31
+ [build-system]
32
+ requires = ["hatchling"]
33
+ build-backend = "hatchling.build"
34
+
35
+ [tool.hatch.build.targets.wheel]
36
+ packages = ["pystac"]
@@ -0,0 +1,167 @@
1
+ """Implements the :stac-ext:`Xarray Assets Extension <xarray>`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Iterable
6
+ from typing import Any, Generic, Literal, TypeVar
7
+
8
+ import pystac
9
+ from pystac.extensions.base import ExtensionManagementMixin, PropertiesExtension
10
+ from pystac.extensions.hooks import ExtensionHooks
11
+
12
+ #: Generalized version of :class:`~pystac.Collection`,
13
+ #: :class:`~pystac.Item`, or :class:`~pystac.Asset`
14
+ T = TypeVar("T", pystac.Collection, pystac.Item, pystac.Asset)
15
+
16
+ SCHEMA_URI = "https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json"
17
+
18
+ PREFIX: str = "xarray:"
19
+ OPEN_KWARGS_PROP = PREFIX + "open_kwargs"
20
+ STORAGE_OPTIONS_PROP = PREFIX + "storage_options"
21
+
22
+
23
+ class XarrayAssetsExtension(
24
+ Generic[T],
25
+ PropertiesExtension,
26
+ ExtensionManagementMixin[pystac.Item | pystac.Collection],
27
+ ):
28
+ """An abstract class that can be used to extend the properties of a
29
+ :class:`~pystac.Collection`, :class:`~pystac.Item`, or :class:`~pystac.Asset` with
30
+ properties from the :stac-ext:`Xarray Assets Extension <xarray>`. This class is
31
+ generic over the type of STAC Object to be extended (e.g. :class:`~pystac.Item`,
32
+ :class:`~pystac.Asset`).
33
+
34
+ To create a concrete instance of :class:`XarrayAssetsExtension`, use the
35
+ :meth:`XarrayAssetsExtension.ext` method. For example:
36
+
37
+ .. code-block:: python
38
+
39
+ >>> item: pystac.Item = ...
40
+ >>> xr_ext = XarrayAssetsExtension.ext(item)
41
+
42
+ """
43
+
44
+ name: Literal["xarray"] = "xarray"
45
+
46
+ @classmethod
47
+ def get_schema_uri(cls) -> str:
48
+ return SCHEMA_URI
49
+
50
+ @classmethod
51
+ def ext(cls, obj: T, add_if_missing: bool = False) -> XarrayAssetsExtension[T]:
52
+ """Extend the given STAC Object with properties from the
53
+ :stac-ext:`XarrayAssets Extension <xarray>`.
54
+
55
+ This extension can be applied to instances of :class:`~pystac.Collection`,
56
+ :class:`~pystac.Item` or :class:`~pystac.Asset`.
57
+
58
+ Raises:
59
+ pystac.ExtensionTypeError : If an invalid object type is passed.
60
+ """
61
+ if isinstance(obj, pystac.Collection):
62
+ cls.ensure_has_extension(obj, add_if_missing)
63
+ return CollectionXarrayAssetsExtension(obj)
64
+ if isinstance(obj, pystac.Item):
65
+ cls.ensure_has_extension(obj, add_if_missing)
66
+ return ItemXarrayAssetsExtension(obj)
67
+ if isinstance(obj, pystac.Asset):
68
+ cls.ensure_owner_has_extension(obj, add_if_missing)
69
+ return AssetXarrayAssetsExtension(obj)
70
+ else:
71
+ raise pystac.ExtensionTypeError(cls._ext_error_message(obj))
72
+
73
+
74
+ class CollectionXarrayAssetsExtension(XarrayAssetsExtension[pystac.Collection]):
75
+ """A concrete implementation of :class:`XarrayAssetsExtension` on a
76
+ :class:`~pystac.Collection` that extends the properties of the Item to include
77
+ properties defined in the :stac-ext:`XarrayAssets Extension <xarray>`.
78
+
79
+ This class should generally not be instantiated directly. Instead, call
80
+ :meth:`XarrayAssetsExtension.ext` on an :class:`~pystac.Collection` to extend it.
81
+ """
82
+
83
+ collection: pystac.Collection
84
+ properties: dict[str, Any]
85
+
86
+ def __init__(self, collection: pystac.Collection):
87
+ self.collection = collection
88
+ self.properties = collection.extra_fields
89
+
90
+ def __repr__(self) -> str:
91
+ return f"<CollectionXarrayAssetsExtension Item id={self.collection.id}>"
92
+
93
+
94
+ class ItemXarrayAssetsExtension(XarrayAssetsExtension[pystac.Item]):
95
+ """A concrete implementation of :class:`XarrayAssetsExtension` on an
96
+ :class:`~pystac.Item` that extends the properties of the Item to include properties
97
+ defined in the :stac-ext:`XarrayAssets Extension <xarray>`.
98
+
99
+ This class should generally not be instantiated directly. Instead, call
100
+ :meth:`XarrayAssetsExtension.ext` on an :class:`~pystac.Item` to extend it.
101
+ """
102
+
103
+ item: pystac.Item
104
+ properties: dict[str, Any]
105
+
106
+ def __init__(self, item: pystac.Item):
107
+ self.item = item
108
+ self.properties = item.properties
109
+
110
+ def __repr__(self) -> str:
111
+ return f"<ItemXarrayAssetsExtension Item id={self.item.id}>"
112
+
113
+
114
+ class AssetXarrayAssetsExtension(XarrayAssetsExtension[pystac.Asset]):
115
+ """A concrete implementation of :class:`XarrayAssetsExtension` on an
116
+ :class:`~pystac.Asset` that extends the Asset fields to include properties defined
117
+ in the :stac-ext:`XarrayAssets Extension <xarray>`.
118
+
119
+ This class should generally not be instantiated directly. Instead, call
120
+ :meth:`XarrayAssetsExtension.ext` on an :class:`~pystac.Asset` to extend it.
121
+ """
122
+
123
+ asset: pystac.Asset
124
+ properties: dict[str, Any]
125
+ additional_read_properties: Iterable[dict[str, Any]] | None = None
126
+
127
+ def __init__(self, asset: pystac.Asset):
128
+ self.asset = asset
129
+ self.properties = asset.extra_fields
130
+ if asset.owner and isinstance(asset.owner, pystac.Item):
131
+ self.additional_read_properties = [asset.owner.properties]
132
+
133
+ @property
134
+ def storage_options(self) -> dict[str, Any] | None:
135
+ """Additional keywords for accessing the dataset from remote storage"""
136
+ return self.properties.get(STORAGE_OPTIONS_PROP)
137
+
138
+ @storage_options.setter
139
+ def storage_options(self, v: dict[str, Any] | None) -> Any:
140
+ if v is None:
141
+ self.properties.pop(STORAGE_OPTIONS_PROP, None)
142
+ else:
143
+ self.properties[STORAGE_OPTIONS_PROP] = v
144
+
145
+ @property
146
+ def open_kwargs(self) -> dict[str, Any] | None:
147
+ """Additional keywords for opening the dataset"""
148
+ return self.properties.get(OPEN_KWARGS_PROP)
149
+
150
+ @open_kwargs.setter
151
+ def open_kwargs(self, v: dict[str, Any] | None) -> Any:
152
+ if v is None:
153
+ self.properties.pop(OPEN_KWARGS_PROP, None)
154
+ else:
155
+ self.properties[OPEN_KWARGS_PROP] = v
156
+
157
+ def __repr__(self) -> str:
158
+ return f"<AssetXarrayAssetsExtension Asset href={self.asset.href}>"
159
+
160
+
161
+ class XarrayAssetsExtensionHooks(ExtensionHooks):
162
+ schema_uri: str = SCHEMA_URI
163
+ prev_extension_ids = {"xarray"}
164
+ stac_object_types = {pystac.STACObjectType.COLLECTION, pystac.STACObjectType.ITEM}
165
+
166
+
167
+ XARRAY_ASSETS_EXTENSION_HOOKS: ExtensionHooks = XarrayAssetsExtensionHooks()
@@ -0,0 +1,54 @@
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers: {}
5
+ method: GET
6
+ uri: https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json
7
+ response:
8
+ body:
9
+ string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\":
10
+ \"https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json#\",\n
11
+ \ \"title\": \"xarray Assets Extension\",\n \"description\": \"xarray Assets
12
+ Extension for STAC Items and STAC Collections.\",\n \"oneOf\": [\n {\n
13
+ \ \"$comment\": \"This is the schema for STAC Items. Remove this object
14
+ if this extension only applies to Collections.\",\n \"allOf\": [\n {\n
15
+ \ \"type\": \"object\",\n \"required\": [\n \"type\",\n
16
+ \ \"properties\",\n \"assets\"\n ],\n \"properties\":
17
+ {\n \"type\": {\n \"const\": \"Feature\"\n },\n
18
+ \ \"properties\": {\n \"allOf\": [\n {\n
19
+ \ \"$comment\": \"Require fields here for item properties.\"\n
20
+ \ },\n {\n \"$ref\": \"#/definitions/fields\"\n
21
+ \ }\n ]\n },\n \"assets\":
22
+ {\n \"type\": \"object\",\n \"additionalProperties\":
23
+ {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
24
+ \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n
25
+ \ }\n ]\n },\n {\n \"$comment\": \"This is the schema
26
+ for STAC Collections. Remove this object if this extension does not define
27
+ top-level fields for Collections AND can't be used in collection assets or
28
+ item asset defintions.\",\n \"allOf\": [\n {\n \"type\":
29
+ \"object\",\n \"required\": [\n \"type\"\n ],\n
30
+ \ \"properties\": {\n \"type\": {\n \"const\":
31
+ \"Collection\"\n },\n \"assets\": {\n \"type\":
32
+ \"object\",\n \"additionalProperties\": {\n \"$ref\":
33
+ \"#/definitions/fields\"\n }\n },\n \"item_assets\":
34
+ {\n \"type\": \"object\",\n \"additionalProperties\":
35
+ {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
36
+ \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n
37
+ \ },\n {\n \"$comment\": \"Remove this object if this
38
+ extension does not define top-level fields for Collections.\",\n \"$ref\":
39
+ \"#/definitions/fields\"\n }\n ]\n }\n ],\n \"definitions\":
40
+ {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\":
41
+ [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\":
42
+ {\n \"type\": \"array\",\n \"contains\": {\n \"const\":
43
+ \"https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json\"\n }\n
44
+ \ }\n }\n },\n \"fields\": {\n \"type\": \"object\",\n
45
+ \ \"properties\": {\n \"xarray:open_kwargs\": {\n \"type\":
46
+ \"object\"\n },\n \"xarray:storage_options\": {\n \"type\":
47
+ \"object\"\n }\n },\n \"patternProperties\": {\n \"^(?!xarray:)\":
48
+ {\n \"$comment\": \"\"\n }\n },\n \"additionalProperties\":
49
+ false\n }\n }\n}"
50
+ headers: {}
51
+ status:
52
+ code: 200
53
+ message: OK
54
+ version: 1
@@ -0,0 +1,54 @@
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers: {}
5
+ method: GET
6
+ uri: https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json
7
+ response:
8
+ body:
9
+ string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\":
10
+ \"https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json#\",\n
11
+ \ \"title\": \"xarray Assets Extension\",\n \"description\": \"xarray Assets
12
+ Extension for STAC Items and STAC Collections.\",\n \"oneOf\": [\n {\n
13
+ \ \"$comment\": \"This is the schema for STAC Items. Remove this object
14
+ if this extension only applies to Collections.\",\n \"allOf\": [\n {\n
15
+ \ \"type\": \"object\",\n \"required\": [\n \"type\",\n
16
+ \ \"properties\",\n \"assets\"\n ],\n \"properties\":
17
+ {\n \"type\": {\n \"const\": \"Feature\"\n },\n
18
+ \ \"properties\": {\n \"allOf\": [\n {\n
19
+ \ \"$comment\": \"Require fields here for item properties.\"\n
20
+ \ },\n {\n \"$ref\": \"#/definitions/fields\"\n
21
+ \ }\n ]\n },\n \"assets\":
22
+ {\n \"type\": \"object\",\n \"additionalProperties\":
23
+ {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
24
+ \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n
25
+ \ }\n ]\n },\n {\n \"$comment\": \"This is the schema
26
+ for STAC Collections. Remove this object if this extension does not define
27
+ top-level fields for Collections AND can't be used in collection assets or
28
+ item asset defintions.\",\n \"allOf\": [\n {\n \"type\":
29
+ \"object\",\n \"required\": [\n \"type\"\n ],\n
30
+ \ \"properties\": {\n \"type\": {\n \"const\":
31
+ \"Collection\"\n },\n \"assets\": {\n \"type\":
32
+ \"object\",\n \"additionalProperties\": {\n \"$ref\":
33
+ \"#/definitions/fields\"\n }\n },\n \"item_assets\":
34
+ {\n \"type\": \"object\",\n \"additionalProperties\":
35
+ {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
36
+ \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n
37
+ \ },\n {\n \"$comment\": \"Remove this object if this
38
+ extension does not define top-level fields for Collections.\",\n \"$ref\":
39
+ \"#/definitions/fields\"\n }\n ]\n }\n ],\n \"definitions\":
40
+ {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\":
41
+ [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\":
42
+ {\n \"type\": \"array\",\n \"contains\": {\n \"const\":
43
+ \"https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json\"\n }\n
44
+ \ }\n }\n },\n \"fields\": {\n \"type\": \"object\",\n
45
+ \ \"properties\": {\n \"xarray:open_kwargs\": {\n \"type\":
46
+ \"object\"\n },\n \"xarray:storage_options\": {\n \"type\":
47
+ \"object\"\n }\n },\n \"patternProperties\": {\n \"^(?!xarray:)\":
48
+ {\n \"$comment\": \"\"\n }\n },\n \"additionalProperties\":
49
+ false\n }\n }\n}"
50
+ headers: {}
51
+ status:
52
+ code: 200
53
+ message: OK
54
+ version: 1
@@ -0,0 +1,54 @@
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers: {}
5
+ method: GET
6
+ uri: https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json
7
+ response:
8
+ body:
9
+ string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\":
10
+ \"https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json#\",\n
11
+ \ \"title\": \"xarray Assets Extension\",\n \"description\": \"xarray Assets
12
+ Extension for STAC Items and STAC Collections.\",\n \"oneOf\": [\n {\n
13
+ \ \"$comment\": \"This is the schema for STAC Items. Remove this object
14
+ if this extension only applies to Collections.\",\n \"allOf\": [\n {\n
15
+ \ \"type\": \"object\",\n \"required\": [\n \"type\",\n
16
+ \ \"properties\",\n \"assets\"\n ],\n \"properties\":
17
+ {\n \"type\": {\n \"const\": \"Feature\"\n },\n
18
+ \ \"properties\": {\n \"allOf\": [\n {\n
19
+ \ \"$comment\": \"Require fields here for item properties.\"\n
20
+ \ },\n {\n \"$ref\": \"#/definitions/fields\"\n
21
+ \ }\n ]\n },\n \"assets\":
22
+ {\n \"type\": \"object\",\n \"additionalProperties\":
23
+ {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
24
+ \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n
25
+ \ }\n ]\n },\n {\n \"$comment\": \"This is the schema
26
+ for STAC Collections. Remove this object if this extension does not define
27
+ top-level fields for Collections AND can't be used in collection assets or
28
+ item asset defintions.\",\n \"allOf\": [\n {\n \"type\":
29
+ \"object\",\n \"required\": [\n \"type\"\n ],\n
30
+ \ \"properties\": {\n \"type\": {\n \"const\":
31
+ \"Collection\"\n },\n \"assets\": {\n \"type\":
32
+ \"object\",\n \"additionalProperties\": {\n \"$ref\":
33
+ \"#/definitions/fields\"\n }\n },\n \"item_assets\":
34
+ {\n \"type\": \"object\",\n \"additionalProperties\":
35
+ {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
36
+ \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n
37
+ \ },\n {\n \"$comment\": \"Remove this object if this
38
+ extension does not define top-level fields for Collections.\",\n \"$ref\":
39
+ \"#/definitions/fields\"\n }\n ]\n }\n ],\n \"definitions\":
40
+ {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\":
41
+ [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\":
42
+ {\n \"type\": \"array\",\n \"contains\": {\n \"const\":
43
+ \"https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json\"\n }\n
44
+ \ }\n }\n },\n \"fields\": {\n \"type\": \"object\",\n
45
+ \ \"properties\": {\n \"xarray:open_kwargs\": {\n \"type\":
46
+ \"object\"\n },\n \"xarray:storage_options\": {\n \"type\":
47
+ \"object\"\n }\n },\n \"patternProperties\": {\n \"^(?!xarray:)\":
48
+ {\n \"$comment\": \"\"\n }\n },\n \"additionalProperties\":
49
+ false\n }\n }\n}"
50
+ headers: {}
51
+ status:
52
+ code: 200
53
+ message: OK
54
+ version: 1
@@ -0,0 +1,54 @@
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers: {}
5
+ method: GET
6
+ uri: https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json
7
+ response:
8
+ body:
9
+ string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\":
10
+ \"https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json#\",\n
11
+ \ \"title\": \"xarray Assets Extension\",\n \"description\": \"xarray Assets
12
+ Extension for STAC Items and STAC Collections.\",\n \"oneOf\": [\n {\n
13
+ \ \"$comment\": \"This is the schema for STAC Items. Remove this object
14
+ if this extension only applies to Collections.\",\n \"allOf\": [\n {\n
15
+ \ \"type\": \"object\",\n \"required\": [\n \"type\",\n
16
+ \ \"properties\",\n \"assets\"\n ],\n \"properties\":
17
+ {\n \"type\": {\n \"const\": \"Feature\"\n },\n
18
+ \ \"properties\": {\n \"allOf\": [\n {\n
19
+ \ \"$comment\": \"Require fields here for item properties.\"\n
20
+ \ },\n {\n \"$ref\": \"#/definitions/fields\"\n
21
+ \ }\n ]\n },\n \"assets\":
22
+ {\n \"type\": \"object\",\n \"additionalProperties\":
23
+ {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
24
+ \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n
25
+ \ }\n ]\n },\n {\n \"$comment\": \"This is the schema
26
+ for STAC Collections. Remove this object if this extension does not define
27
+ top-level fields for Collections AND can't be used in collection assets or
28
+ item asset defintions.\",\n \"allOf\": [\n {\n \"type\":
29
+ \"object\",\n \"required\": [\n \"type\"\n ],\n
30
+ \ \"properties\": {\n \"type\": {\n \"const\":
31
+ \"Collection\"\n },\n \"assets\": {\n \"type\":
32
+ \"object\",\n \"additionalProperties\": {\n \"$ref\":
33
+ \"#/definitions/fields\"\n }\n },\n \"item_assets\":
34
+ {\n \"type\": \"object\",\n \"additionalProperties\":
35
+ {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
36
+ \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n
37
+ \ },\n {\n \"$comment\": \"Remove this object if this
38
+ extension does not define top-level fields for Collections.\",\n \"$ref\":
39
+ \"#/definitions/fields\"\n }\n ]\n }\n ],\n \"definitions\":
40
+ {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\":
41
+ [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\":
42
+ {\n \"type\": \"array\",\n \"contains\": {\n \"const\":
43
+ \"https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json\"\n }\n
44
+ \ }\n }\n },\n \"fields\": {\n \"type\": \"object\",\n
45
+ \ \"properties\": {\n \"xarray:open_kwargs\": {\n \"type\":
46
+ \"object\"\n },\n \"xarray:storage_options\": {\n \"type\":
47
+ \"object\"\n }\n },\n \"patternProperties\": {\n \"^(?!xarray:)\":
48
+ {\n \"$comment\": \"\"\n }\n },\n \"additionalProperties\":
49
+ false\n }\n }\n}"
50
+ headers: {}
51
+ status:
52
+ code: 200
53
+ message: OK
54
+ version: 1
@@ -0,0 +1,61 @@
1
+ {
2
+ "stac_version": "1.1.0",
3
+ "stac_extensions": [
4
+ "https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json"
5
+ ],
6
+ "type": "Collection",
7
+ "id": "collection",
8
+ "title": "A title",
9
+ "description": "A description",
10
+ "license": "Apache-2.0",
11
+ "extent": {
12
+ "spatial": {
13
+ "bbox": [
14
+ [
15
+ 172.9,
16
+ 1.3,
17
+ 173,
18
+ 1.4
19
+ ]
20
+ ]
21
+ },
22
+ "temporal": {
23
+ "interval": [
24
+ [
25
+ "2015-06-23T00:00:00Z",
26
+ null
27
+ ]
28
+ ]
29
+ }
30
+ },
31
+ "assets": {
32
+ "example": {
33
+ "href": "abfs://cpdata/raw/terraclimate/4000m/raster.zarr",
34
+ "type": "application/vnd+zarr",
35
+ "xarray:storage_options": {
36
+ "account_name": "cpdataeuwest"
37
+ },
38
+ "xarray:open_kwargs": {
39
+ "consolidated": true
40
+ }
41
+ }
42
+ },
43
+ "summaries": {
44
+ "datetime": {
45
+ "minimum": "2015-06-23T00:00:00Z",
46
+ "maximum": "2019-07-10T13:44:56Z"
47
+ }
48
+ },
49
+ "links": [
50
+ {
51
+ "href": "./collection.json",
52
+ "rel": "root",
53
+ "title": "A title",
54
+ "type": "application/json"
55
+ },
56
+ {
57
+ "href": "./item.json",
58
+ "rel": "item"
59
+ }
60
+ ]
61
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "stac_version": "1.1.0",
3
+ "stac_extensions": [
4
+ "https://stac-extensions.github.io/xarray-assets/v1.0.0/schema.json"
5
+ ],
6
+ "type": "Feature",
7
+ "id": "item",
8
+ "bbox": [
9
+ 172.9,
10
+ 1.3,
11
+ 173,
12
+ 1.4
13
+ ],
14
+ "geometry": {
15
+ "type": "Polygon",
16
+ "coordinates": [
17
+ [
18
+ [
19
+ 172.9,
20
+ 1.3
21
+ ],
22
+ [
23
+ 173,
24
+ 1.3
25
+ ],
26
+ [
27
+ 173,
28
+ 1.4
29
+ ],
30
+ [
31
+ 172.9,
32
+ 1.4
33
+ ],
34
+ [
35
+ 172.9,
36
+ 1.3
37
+ ]
38
+ ]
39
+ ]
40
+ },
41
+ "properties": {
42
+ "datetime": "2020-12-11T22:38:32Z"
43
+ },
44
+ "links": [],
45
+ "assets": {
46
+ "data": {
47
+ "href": "abfs://example.com/examples/file.zarr",
48
+ "xarray:storage_options": {
49
+ "account_name": "test-account"
50
+ },
51
+ "xarray:open_kwargs": {
52
+ "consolidated": true
53
+ }
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,162 @@
1
+ """Tests for pystac.tests.extensions.xarray_assets"""
2
+
3
+ import json
4
+ from pathlib import Path
5
+
6
+ import pytest
7
+
8
+ import pystac
9
+ from pystac.extensions.xarray_assets import XarrayAssetsExtension
10
+
11
+ DATA_FILES = Path(__file__).resolve().parent / "data-files"
12
+
13
+
14
+ @pytest.fixture
15
+ def ext_collection_uri() -> str:
16
+ return str(DATA_FILES / "collection.json")
17
+
18
+
19
+ @pytest.fixture
20
+ def ext_collection(ext_collection_uri: str) -> pystac.Collection:
21
+ return pystac.Collection.from_file(ext_collection_uri)
22
+
23
+
24
+ @pytest.fixture
25
+ def ext_item_uri() -> str:
26
+ return str(DATA_FILES / "item.json")
27
+
28
+
29
+ @pytest.fixture
30
+ def ext_item(ext_item_uri: str) -> pystac.Item:
31
+ return pystac.Item.from_file(ext_item_uri)
32
+
33
+
34
+ @pytest.fixture
35
+ def ext_asset(ext_item: pystac.Item) -> pystac.Asset:
36
+ return ext_item.assets["data"]
37
+
38
+
39
+ def test_item_stac_extensions(ext_item: pystac.Item) -> None:
40
+ assert XarrayAssetsExtension.has_extension(ext_item)
41
+
42
+
43
+ def test_collection_stac_extensions(ext_collection: pystac.Collection) -> None:
44
+ assert XarrayAssetsExtension.has_extension(ext_collection)
45
+
46
+
47
+ def test_item_get_schema_uri(ext_item: pystac.Item) -> None:
48
+ assert XarrayAssetsExtension.get_schema_uri() in ext_item.stac_extensions
49
+
50
+
51
+ def test_collection_get_schema_uri(ext_collection: pystac.Collection) -> None:
52
+ assert XarrayAssetsExtension.get_schema_uri() in ext_collection.stac_extensions
53
+
54
+
55
+ def test_ext_raises_if_item_does_not_conform(item: pystac.Item) -> None:
56
+ with pytest.raises(pystac.errors.ExtensionNotImplemented):
57
+ XarrayAssetsExtension.ext(item)
58
+
59
+
60
+ def test_ext_raises_if_collection_does_not_conform(
61
+ collection: pystac.Collection,
62
+ ) -> None:
63
+ with pytest.raises(pystac.errors.ExtensionNotImplemented):
64
+ XarrayAssetsExtension.ext(collection)
65
+
66
+
67
+ def test_ext_raises_on_catalog(catalog: pystac.Catalog) -> None:
68
+ with pytest.raises(
69
+ pystac.errors.ExtensionTypeError,
70
+ match="XarrayAssetsExtension does not apply to type 'Catalog'",
71
+ ):
72
+ XarrayAssetsExtension.ext(catalog) # type: ignore
73
+
74
+
75
+ def test_item_to_from_dict(ext_item_uri: str, ext_item: pystac.Item) -> None:
76
+ with open(ext_item_uri) as f:
77
+ d = json.load(f)
78
+ actual = ext_item.to_dict(include_self_link=False)
79
+ assert actual == d
80
+
81
+
82
+ def test_collection_to_from_dict(
83
+ ext_collection_uri: str, ext_collection: pystac.Item
84
+ ) -> None:
85
+ with open(ext_collection_uri) as f:
86
+ d = json.load(f)
87
+ actual = ext_collection.to_dict(include_self_link=False)
88
+ assert actual == d
89
+
90
+
91
+ def test_add_to_item(item: pystac.Item) -> None:
92
+ assert not XarrayAssetsExtension.has_extension(item)
93
+ XarrayAssetsExtension.add_to(item)
94
+
95
+ assert XarrayAssetsExtension.has_extension(item)
96
+
97
+
98
+ def test_add_to_collection(collection: pystac.Collection) -> None:
99
+ assert not XarrayAssetsExtension.has_extension(collection)
100
+ XarrayAssetsExtension.add_to(collection)
101
+
102
+ assert XarrayAssetsExtension.has_extension(collection)
103
+
104
+
105
+ @pytest.mark.vcr
106
+ def test_item_validate(ext_item: pystac.Item) -> None:
107
+ assert ext_item.validate()
108
+
109
+
110
+ @pytest.mark.vcr
111
+ def test_collection_validate(ext_collection: pystac.Collection) -> None:
112
+ assert ext_collection.validate()
113
+
114
+
115
+ def test_fields_are_not_on_item(ext_item: pystac.Item) -> None:
116
+ assert not hasattr(XarrayAssetsExtension.ext(ext_item), "storage_options")
117
+ assert not hasattr(XarrayAssetsExtension.ext(ext_item), "open_kwargs")
118
+
119
+
120
+ def test_fields_are_not_on_collection(ext_collection: pystac.Item) -> None:
121
+ assert not hasattr(XarrayAssetsExtension.ext(ext_collection), "storage_options")
122
+ assert not hasattr(XarrayAssetsExtension.ext(ext_collection), "open_kwargs")
123
+
124
+
125
+ @pytest.mark.parametrize("field", ["storage_options", "open_kwargs"])
126
+ def test_get_field(ext_asset: pystac.Asset, field: str) -> None:
127
+ prop = ext_asset.extra_fields[f"xarray:{field}"]
128
+ attr = getattr(XarrayAssetsExtension.ext(ext_asset), field)
129
+
130
+ assert attr is not None
131
+ assert attr == prop
132
+
133
+
134
+ @pytest.mark.parametrize(
135
+ "field,value",
136
+ [
137
+ ("storage_options", {"anon": True}),
138
+ ("open_kwargs", {"engine": "zarr"}),
139
+ ],
140
+ )
141
+ @pytest.mark.vcr
142
+ def test_set_field(ext_asset: pystac.Asset, field: str, value) -> None: # type: ignore
143
+ original = ext_asset.extra_fields[f"xarray:{field}"]
144
+ setattr(XarrayAssetsExtension.ext(ext_asset), field, value)
145
+ new = ext_asset.extra_fields[f"xarray:{field}"]
146
+
147
+ assert new != original
148
+ assert new == value
149
+
150
+ item = ext_asset.owner
151
+ assert item is not None
152
+ assert isinstance(item, pystac.Item)
153
+ assert item.validate()
154
+
155
+
156
+ @pytest.mark.parametrize("field", ["storage_options", "open_kwargs"])
157
+ def test_set_field_to_none_pops_from_dict(ext_asset: pystac.Asset, field: str) -> None:
158
+ prop_name = f"xarray:{field}"
159
+ assert prop_name in ext_asset.extra_fields
160
+
161
+ setattr(XarrayAssetsExtension.ext(ext_asset), field, None)
162
+ assert prop_name not in ext_asset.extra_fields