From 0d944c8a945bc2a2c056d84a97731ff40b6e1ee3 Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Tue, 21 Jan 2025 16:39:07 -0500 Subject: [PATCH 1/3] Fix up docs linking --- .github/workflows/continuous-integration.yml | 2 +- docs/api.rst | 4 +- docs/api/asset.rst | 7 +- docs/api/catalog.rst | 7 +- docs/api/collection.rst | 7 +- docs/api/extensions.rst | 3 +- docs/api/extensions/ext.rst | 7 ++ docs/api/extensions/render.rst | 6 ++ docs/api/item.rst | 7 +- docs/api/item_collection.rst | 7 +- docs/api/link.rst | 7 +- docs/api/pystac.rst | 16 ++++ docs/api/serialization/identify.rst | 15 +++- docs/api/stac_object.rst | 14 ++- docs/api/summaries.rst | 7 +- docs/api/utils.rst | 4 + docs/api/validation.rst | 1 + docs/api/validation/local_validator.rst | 6 ++ docs/api/validation/stac_validator.rst | 6 ++ docs/concepts.rst | 36 ++++---- docs/conf.py | 8 ++ docs/tutorials/creating-a-landsat-stac.ipynb | 4 +- .../how-to-create-stac-catalogs.ipynb | 4 +- pystac/asset.py | 3 +- pystac/catalog.py | 12 +-- pystac/collection.py | 12 ++- pystac/common_metadata.py | 4 +- pystac/extensions/base.py | 6 +- pystac/extensions/classification.py | 13 +-- pystac/extensions/datacube.py | 8 +- pystac/extensions/eo.py | 11 +-- pystac/extensions/ext.py | 88 ++++++++++++++++++- pystac/extensions/file.py | 5 +- pystac/extensions/grid.py | 10 ++- pystac/extensions/label.py | 10 +-- pystac/extensions/mgrs.py | 10 ++- pystac/extensions/pointcloud.py | 11 +-- pystac/extensions/projection.py | 11 +-- pystac/extensions/raster.py | 27 +++--- pystac/extensions/render.py | 81 +++++++---------- pystac/extensions/sar.py | 25 +++--- pystac/extensions/sat.py | 11 +-- pystac/extensions/scientific.py | 11 +-- pystac/extensions/storage.py | 13 +-- pystac/extensions/table.py | 6 +- pystac/extensions/timestamps.py | 14 +-- pystac/extensions/version.py | 14 +-- pystac/extensions/view.py | 12 +-- pystac/extensions/xarray_assets.py | 6 +- pystac/item.py | 1 + pystac/item_collection.py | 35 ++++---- pystac/link.py | 9 +- pystac/serialization/identify.py | 8 +- pystac/serialization/migrate.py | 2 +- pystac/stac_io.py | 3 +- pystac/stac_object.py | 33 ++++--- pystac/summaries.py | 3 +- pystac/utils.py | 9 +- pystac/validation/__init__.py | 38 ++++---- pystac/validation/stac_validator.py | 9 +- tests/extensions/test_custom.py | 4 +- 61 files changed, 498 insertions(+), 275 deletions(-) create mode 100644 docs/api/extensions/ext.rst create mode 100644 docs/api/extensions/render.rst create mode 100644 docs/api/validation/local_validator.rst diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index d7d4dc397..bae172d1f 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -161,4 +161,4 @@ jobs: - name: Install pystac run: uv sync --no-dev && uv sync --package pystac-docs --inexact - name: Check docs - run: uv run make -C docs html SPHINXOPTS="-W --keep-going" + run: uv run make -C docs html SPHINXOPTS="-W --keep-going -n" diff --git a/docs/api.rst b/docs/api.rst index 8aaba28ce..66d55e50a 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -191,9 +191,7 @@ Serialization The ``pystac.serialization`` sub-package contains tools used internally by PySTAC to identify, serialize, and migrate STAC objects: -* :mod:`pystac.serialization.identify`: Tools for identifying STAC objects -* :mod:`pystac.serialization.migrate`: Tools for migrating STAC objects from a previous - STAC Spec version. +* :mod:`pystac.serialization`: Tools for identifying and migrating STAC objects Validation diff --git a/docs/api/asset.rst b/docs/api/asset.rst index ab02001f2..062108ead 100644 --- a/docs/api/asset.rst +++ b/docs/api/asset.rst @@ -1,7 +1,12 @@ pystac.asset ============ -.. automodule:: pystac.asset +.. autoclass:: pystac.asset.Asset :members: :undoc-members: :noindex: + +.. automodule:: pystac.asset + :members: + :undoc-members: + :exclude-members: Asset diff --git a/docs/api/catalog.rst b/docs/api/catalog.rst index 45c4bd1c8..99bfd1290 100644 --- a/docs/api/catalog.rst +++ b/docs/api/catalog.rst @@ -1,7 +1,12 @@ pystac.catalog ============== -.. automodule:: pystac.catalog +.. autoclass:: pystac.catalog.Catalog :members: :undoc-members: :noindex: + +.. automodule:: pystac.catalog + :members: + :undoc-members: + :exclude-members: Catalog diff --git a/docs/api/collection.rst b/docs/api/collection.rst index d3728687b..de435c23a 100644 --- a/docs/api/collection.rst +++ b/docs/api/collection.rst @@ -1,7 +1,12 @@ pystac.collection ================= -.. automodule:: pystac.collection +.. autoclass:: pystac.collection.Collection :members: :undoc-members: :noindex: + +.. automodule:: pystac.collection + :members: + :undoc-members: + :exclude-members: Collection diff --git a/docs/api/extensions.rst b/docs/api/extensions.rst index 6ba0ceee3..44cc8af32 100644 --- a/docs/api/extensions.rst +++ b/docs/api/extensions.rst @@ -13,8 +13,8 @@ pystac.extensions .. autosummary:: - datacube.DatacubeExtension classification.ClassificationExtension + datacube.DatacubeExtension eo.EOExtension file.FileExtension grid.GridExtension @@ -23,6 +23,7 @@ pystac.extensions pointcloud.PointcloudExtension projection.ProjectionExtension raster.RasterExtension + render.RenderExtension sar.SarExtension sat.SatExtension scientific.ScientificExtension diff --git a/docs/api/extensions/ext.rst b/docs/api/extensions/ext.rst new file mode 100644 index 000000000..23708b444 --- /dev/null +++ b/docs/api/extensions/ext.rst @@ -0,0 +1,7 @@ +pytac.extensions.ext +==================== + +.. automodule:: pystac.extensions.ext + :members: + :inherited-members: + :undoc-members: diff --git a/docs/api/extensions/render.rst b/docs/api/extensions/render.rst new file mode 100644 index 000000000..b7b13ba1e --- /dev/null +++ b/docs/api/extensions/render.rst @@ -0,0 +1,6 @@ +pystac.extensions.render +======================== + +.. automodule:: pystac.extensions.render + :members: + :undoc-members: diff --git a/docs/api/item.rst b/docs/api/item.rst index 921794cea..aedf84bcd 100644 --- a/docs/api/item.rst +++ b/docs/api/item.rst @@ -1,7 +1,12 @@ pystac.item =========== -.. automodule:: pystac.item +.. autoclass:: pystac.item.Item :members: :undoc-members: :noindex: + +.. automodule:: pystac.item + :members: + :undoc-members: + :exclude-members: Item diff --git a/docs/api/item_collection.rst b/docs/api/item_collection.rst index 5958c289a..9b01f7afa 100644 --- a/docs/api/item_collection.rst +++ b/docs/api/item_collection.rst @@ -1,7 +1,12 @@ pystac.item_collection ====================== -.. automodule:: pystac.item_collection +.. autoclass:: pystac.item_collection.ItemCollection :members: :undoc-members: :noindex: + +.. automodule:: pystac.item_collection + :members: + :undoc-members: + :exclude-members: ItemCollection diff --git a/docs/api/link.rst b/docs/api/link.rst index 85b1195b9..9756ef0b6 100644 --- a/docs/api/link.rst +++ b/docs/api/link.rst @@ -1,7 +1,12 @@ pystac.link =========== -.. automodule:: pystac.link +.. autoclass:: pystac.link.Link :members: :undoc-members: :noindex: + +.. automodule:: pystac.link + :members: + :undoc-members: + :exclude-members: Link diff --git a/docs/api/pystac.rst b/docs/api/pystac.rst index d1c676955..a325710eb 100644 --- a/docs/api/pystac.rst +++ b/docs/api/pystac.rst @@ -44,6 +44,7 @@ Catalog .. autoclass:: pystac.Catalog :members: + :inherited-members: :undoc-members: CatalogType @@ -59,6 +60,7 @@ Collection .. autoclass:: pystac.Collection :members: + :inherited-members: :undoc-members: Extent @@ -108,6 +110,7 @@ Item .. autoclass:: pystac.Item :members: + :inherited-members: :undoc-members: Asset @@ -137,12 +140,14 @@ ItemCollection .. autoclass:: pystac.ItemCollection :members: + :inherited-members: Link ---- .. autoclass:: pystac.Link :members: + :inherited-members: :undoc-members: MediaType @@ -208,3 +213,14 @@ STACValidationError ~~~~~~~~~~~~~~~~~~~ .. autoclass:: pystac.STACValidationError + +TemplateError +~~~~~~~~~~~~~ + +.. autoclass:: pystac.TemplateError + + +DeprecatedWarning +~~~~~~~~~~~~~~~~~ + +.. autoclass:: pystac.DeprecatedWarning diff --git a/docs/api/serialization/identify.rst b/docs/api/serialization/identify.rst index 47b55fea7..a54e38f62 100644 --- a/docs/api/serialization/identify.rst +++ b/docs/api/serialization/identify.rst @@ -1,7 +1,20 @@ pystac.serialization.identify ============================= + +.. automodule:: pystac.serialization.identify + :members: STACVersionRange, identify_stac_object, identify_stac_object_type + :undoc-members: + :noindex: + + +.. autoclass:: pystac.serialization.identify.STACVersionRange + :members: + :undoc-members: + :noindex: + + .. automodule:: pystac.serialization.identify :members: :undoc-members: - :noindex: + :exclude-members: STACVersionRange, identify_stac_object, identify_stac_object_type diff --git a/docs/api/stac_object.rst b/docs/api/stac_object.rst index 1b94928a9..a5a37fcec 100644 --- a/docs/api/stac_object.rst +++ b/docs/api/stac_object.rst @@ -1,7 +1,19 @@ pystac.stac_object ================== -.. automodule:: pystac.stac_object +.. autoclass:: pystac.stac_object.STACObject + :members: + :undoc-members: + :noindex: + +.. autoclass:: pystac.stac_object.STACObjectType :members: :undoc-members: :noindex: + +.. automodule:: pystac.stac_object + :members: + :undoc-members: + :exclude-members: STACObject, STACObjectType + +.. autoclass:: pystac.stac_object.S diff --git a/docs/api/summaries.rst b/docs/api/summaries.rst index 7a2358f08..e7a7191d8 100644 --- a/docs/api/summaries.rst +++ b/docs/api/summaries.rst @@ -1,7 +1,12 @@ pystac.summaries ================ -.. automodule:: pystac.summaries +.. autoclass:: pystac.summaries.Summaries :members: :undoc-members: :noindex: + +.. automodule:: pystac.summaries + :members: + :undoc-members: + :exclude-members: Summaries diff --git a/docs/api/utils.rst b/docs/api/utils.rst index 7417438ee..83f148ccf 100644 --- a/docs/api/utils.rst +++ b/docs/api/utils.rst @@ -4,3 +4,7 @@ pystac.utils .. automodule:: pystac.utils :members: :undoc-members: + +.. autoclass:: pystac.utils.T + +.. autoclass:: pystac.utils.U diff --git a/docs/api/validation.rst b/docs/api/validation.rst index 4b73d714b..67f0ff09b 100644 --- a/docs/api/validation.rst +++ b/docs/api/validation.rst @@ -10,3 +10,4 @@ pystac.validation .. automodule:: pystac.validation :members: + :undoc-members: diff --git a/docs/api/validation/local_validator.rst b/docs/api/validation/local_validator.rst new file mode 100644 index 000000000..09096e349 --- /dev/null +++ b/docs/api/validation/local_validator.rst @@ -0,0 +1,6 @@ +pystac.validation.local\_validator +================================== + +.. automodule:: pystac.validation.local_validator + :members: + :undoc-members: diff --git a/docs/api/validation/stac_validator.rst b/docs/api/validation/stac_validator.rst index 84b53abab..651a5c669 100644 --- a/docs/api/validation/stac_validator.rst +++ b/docs/api/validation/stac_validator.rst @@ -1,6 +1,12 @@ pystac.validation.stac\_validator ================================= +.. autoclass:: pystac.validation.stac_validator.JsonSchemaSTACValidator + :members: + :undoc-members: + :noindex: + .. automodule:: pystac.validation.stac_validator :members: :undoc-members: + :exclude-members: JsonSchemaSTACValidator diff --git a/docs/concepts.rst b/docs/concepts.rst index 6c26c6dec..2c320f1e1 100644 --- a/docs/concepts.rst +++ b/docs/concepts.rst @@ -235,7 +235,7 @@ in the catalog will produce a relative link, based on the self link of the paren object. You can make all the links of a catalog relative or absolute by setting the -:func:`Catalog.catalog_type` field then resaving the entire catalog. +:func:`~pystac.Catalog.catalog_type` field then resaving the entire catalog. .. _rel vs abs asset: @@ -312,7 +312,7 @@ that you see all API calls. If you require more custom logic for I/O operations or would like to use a 3rd-party library for I/O operations (e.g. ``requests``), you can create a sub-class of :class:`pystac.StacIO` -(or :class:`pystac.DefaultStacIO`) and customize the methods as +(or :class:`pystac.stac_io.DefaultStacIO`) and customize the methods as you see fit. You can then pass instances of this custom sub-class into the ``stac_io`` argument of most object-specific I/O methods. You can also use :meth:`pystac.StacIO.set_default` in your client's ``__init__.py`` file to make this @@ -573,7 +573,7 @@ PySTAC package) or older versions (which are hosted at https://schemas.stacspec. This validation includes any extensions that the object extends (these are always accessed remotely based on their URIs). -If there are validation errors, a :class:`~pystac.validation.STACValidationError` +If there are validation errors, a :class:`~pystac.STACValidationError` is raised. You can also call :meth:`~pystac.Catalog.validate_all` on a Catalog or Collection to @@ -587,7 +587,7 @@ Validating STAC JSON -------------------- You can validate STAC JSON represented as a ``dict`` using the -:meth:`pystac.validation.validate_dict` method: +:func:`pystac.validation.validate_dict` method: .. code-block:: python @@ -599,7 +599,7 @@ You can validate STAC JSON represented as a ``dict`` using the validate_dict(js) You can also recursively validate all of the catalogs, collections and items across STAC -versions using the :meth:`pystac.validation.validate_all` method: +versions using the :func:`pystac.validation.validate_all` method: .. code-block:: python @@ -615,15 +615,16 @@ Using your own validator By default PySTAC uses the :class:`~pystac.validation.JsonSchemaSTACValidator` implementation for validation. Users can define their own implementations of -:class:`~pystac.validation.STACValidator` and register it with pystac using -:meth:`pystac.validation.set_validator`. +:class:`~pystac.validation.stac_validator.STACValidator` and register it with pystac +using :func:`pystac.validation.set_validator`. The :class:`~pystac.validation.JsonSchemaSTACValidator` takes a -:class:`~pystac.validation.SchemaUriMap`, which by default uses the -:class:`~pystac.validation.schema_uri_map.DefaultSchemaUriMap`. If desirable, users cn -create their own implementation of :class:`~pystac.validation.SchemaUriMap` and register +:class:`~pystac.validation.schema_uri_map.SchemaUriMap`, which by default uses the +:class:`~pystac.validation.schema_uri_map.DefaultSchemaUriMap`. If desirable, users can +create their own implementation of +:class:`~pystac.validation.schema_uri_map.SchemaUriMap` and register a new instance of :class:`~pystac.validation.JsonSchemaSTACValidator` using that schema -map with :meth:`pystac.validation.set_validator`. +map with :func:`pystac.validation.set_validator`. Extensions ========== @@ -673,7 +674,8 @@ Extension `, you can access the fields associated with that extension using the `Adding an Extension`_ section below for details on adding an extension to an object. -If you don't want to raise an error you can use :meth:`~pystac.Item.ext.has` +If you don't want to raise an error you can use +:meth:`Item.ext.has ` to first check if the extension is implemented on your pystac object: .. code-block:: python @@ -726,11 +728,9 @@ Adding an Extension ------------------- You can add an extension to a STAC object that does not already implement that extension -using the :meth:`~pystac.Item.ext.add` method. Any concrete -extension implementations that extend existing STAC objects should have -this method available. The :meth:`~pystac.Item.ext.add` method adds the correct schema -URI to the :attr:`~pystac.Item.stac_extensions` list for the object being -extended. +using the :meth:`Item.ext.add ` method. +The :meth:`Item.ext.add ` method adds the correct +schema URI to the :attr:`~pystac.Item.stac_extensions` list for the STAC object. .. code-block:: python @@ -927,7 +927,7 @@ in the catalog to have a unique identifier, which is unique across the entire ST When a link is being resolved from a STACObject that has it's root set, that root is passed into the :func:`Link.resolve_stac_object ` call. -That root's :class:`~pystac.resolved_object_cache.ResolvedObjectCache` will be used to +That root's :class:`~pystac.cache.ResolvedObjectCache` will be used to ensure that if the link is pointing to an object that has already been resolved, then that link will point to the same, single instance in the cache. This ensures working with STAC objects in memory doesn't create a situation where multiple copies of the same diff --git a/docs/conf.py b/docs/conf.py index 12c9861fe..d6a3a667d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -248,3 +248,11 @@ # -- Substutition variables rst_epilog = f".. |stac_version| replace:: {STACVersion.DEFAULT_STAC_VERSION}" + +nitpick_ignore = [ + ("py:class", "Datetime"), + ("py:class", "L"), + ("py:class", "pystac.summaries.T"), + ("py:class", "HREF"), # this one partially works + ("py:class", "jsonschema.validators.Draft7Validator"), +] diff --git a/docs/tutorials/creating-a-landsat-stac.ipynb b/docs/tutorials/creating-a-landsat-stac.ipynb index 7663734c2..3845ac8e0 100644 --- a/docs/tutorials/creating-a-landsat-stac.ipynb +++ b/docs/tutorials/creating-a-landsat-stac.ipynb @@ -2521,7 +2521,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "pystac", "language": "python", "name": "python3" }, @@ -2535,7 +2535,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.3" + "version": "3.11.6" } }, "nbformat": 4, diff --git a/docs/tutorials/how-to-create-stac-catalogs.ipynb b/docs/tutorials/how-to-create-stac-catalogs.ipynb index 3750d029c..18fb87a74 100644 --- a/docs/tutorials/how-to-create-stac-catalogs.ipynb +++ b/docs/tutorials/how-to-create-stac-catalogs.ipynb @@ -3587,7 +3587,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "pystac", "language": "python", "name": "python3" }, @@ -3601,7 +3601,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.1" + "version": "3.11.6" } }, "nbformat": 4, diff --git a/pystac/asset.py b/pystac/asset.py index 509eac9da..7fbafead9 100644 --- a/pystac/asset.py +++ b/pystac/asset.py @@ -14,6 +14,7 @@ from pystac.common_metadata import CommonMetadata from pystac.extensions.ext import AssetExt +#: Generalized version of :class:`Asset` A = TypeVar("A", bound="Asset") @@ -254,7 +255,7 @@ def copy(self, href: str) -> Asset: def delete(self) -> None: """Delete this asset's file. Does not delete the asset from the item - that owns it. See :func:`~pystac.Item.delete_asset` for that. + that owns it. See :meth:`~pystac.Item.delete_asset` for that. Does not modify the asset. """ diff --git a/pystac/catalog.py b/pystac/catalog.py index 88228878a..1299bbd1d 100644 --- a/pystac/catalog.py +++ b/pystac/catalog.py @@ -9,7 +9,6 @@ TYPE_CHECKING, Any, TypeVar, - Union, cast, ) @@ -42,6 +41,7 @@ from pystac.extensions.ext import CatalogExt from pystac.item import Item +#: Generalized version of :class:`Catalog` C = TypeVar("C", bound="Catalog") @@ -402,7 +402,7 @@ def get_child( will improve performance. Defaults to True. Return: - Optional Catalog or Collection: The child with the given ID, + Catalog or Collection or None: The child with the given ID, or None if not found. """ if not recursive: @@ -418,7 +418,7 @@ def sort_function(links: list[Link]) -> list[Link]: ) children = map( - lambda x: cast(Union[pystac.Catalog, pystac.Collection], x), + lambda x: cast(pystac.Catalog | pystac.Collection, x), self.get_stac_objects( pystac.RelType.CHILD, modify_links=sort_function ), @@ -439,7 +439,7 @@ def get_children(self) -> Iterable[Catalog | Collection]: is this catalog. """ return map( - lambda x: cast(Union[pystac.Catalog, pystac.Collection], x), + lambda x: cast(pystac.Catalog | pystac.Collection, x), self.get_stac_objects(pystac.RelType.CHILD), ) @@ -820,7 +820,7 @@ def process_catalog( link.resolve_stac_object(root=self.get_root()) setter_funcs.extend( process_catalog( - cast(Union[pystac.Catalog, pystac.Collection], link.target), + cast(pystac.Catalog | pystac.Collection, link.target), new_root, is_root=False, parent=cat, @@ -867,7 +867,7 @@ def generate_subcatalogs( template, no subcatalog is added. Returns: - [catalog]: List of new catalogs created + list[Catalog]: List of new catalogs created """ result: list[Catalog] = [] parent_ids = parent_ids or list() diff --git a/pystac/collection.py b/pystac/collection.py index 63fd63619..77531e4b8 100644 --- a/pystac/collection.py +++ b/pystac/collection.py @@ -9,7 +9,6 @@ Any, Optional, TypeVar, - Union, cast, ) @@ -39,13 +38,12 @@ from pystac.extensions.ext import CollectionExt from pystac.item import Item +#: Generalized version of :class:`Collection` C = TypeVar("C", bound="Collection") -Bboxes = list[list[Union[float, int]]] -TemporalIntervals = Union[list[list[datetime]], list[list[Optional[datetime]]]] -TemporalIntervalsLike = Union[ - TemporalIntervals, list[datetime], list[Optional[datetime]] -] +Bboxes = list[list[float | int]] +TemporalIntervals = list[list[datetime]] | list[list[Optional[datetime]]] +TemporalIntervalsLike = TemporalIntervals | list[datetime] | list[Optional[datetime]] class SpatialExtent: @@ -82,7 +80,7 @@ def __init__( # A common mistake is to pass in a single bbox instead of a list of bboxes. # Account for this by transforming the input in that case. if isinstance(bboxes[0], (float, int)): - self.bboxes = [cast(list[Union[float, int]], bboxes)] + self.bboxes = [cast(list[float | int], bboxes)] else: self.bboxes = cast(Bboxes, bboxes) diff --git a/pystac/common_metadata.py b/pystac/common_metadata.py index b7d7fbfc5..4dac97dae 100644 --- a/pystac/common_metadata.py +++ b/pystac/common_metadata.py @@ -206,7 +206,7 @@ def created(self) -> datetime | None: ``created`` has a different meaning depending on the type of STAC object. On an :class:`~pystac.Item`, it refers to the creation time of the metadata. On an :class:`~pystac.Asset`, it refers to the creation time of - the actual data linked to in :attr:`Asset.href datetime | None: ``updated`` has a different meaning depending on the type of STAC object. On an :class:`~pystac.Item`, it refers to the update time of the metadata. On an :class:`~pystac.Asset`, it refers to the update time of - the actual data linked to in :attr:`Asset.href dict[str, Any]: class ClassificationExtension( Generic[T], PropertiesExtension, - ExtensionManagementMixin[Union[pystac.Item, pystac.Collection]], + ExtensionManagementMixin[pystac.Item | pystac.Collection], ): """An abstract class that can be used to extend the properties of :class:`~pystac.Item`, :class:`~pystac.Asset`, - :class:`~pystac.extension.raster.RasterBand`, or + :class:`~pystac.extensions.raster.RasterBand`, or :class:`~pystac.ItemAssetDefinition` with properties from the :stac-ext:`Classification Extension `. This class is generic over the type of STAC object being extended. @@ -509,13 +510,13 @@ def apply( classes: list[Classification] | None = None, bitfields: list[Bitfield] | None = None, ) -> None: - """Applies the classifiation extension fields to the extended object. + """Applies the classification extension fields to the extended object. Note: one may set either the classes or bitfields objects, but not both. Args: classes: a list of - :class:`~pystac.extension.classification.Classification` objects + :class:`~pystac.extensions.classification.Classification` objects describing the various classes in the classification """ assert ( @@ -602,7 +603,7 @@ def ext(cls, obj: T, add_if_missing: bool = False) -> ClassificationExtension[T] This extension can be applied to instances of :class:`~pystac.Item`, :class:`~pystac.Asset`, :class:`~pystac.ItemAssetDefinition`, or - :class:`~pystac.extension.raster.RasterBand`. + :class:`~pystac.extensions.raster.RasterBand`. Raises: pystac.ExtensionTypeError : If an invalid object type is passed diff --git a/pystac/extensions/datacube.py b/pystac/extensions/datacube.py index a2eecc0c6..77623848a 100644 --- a/pystac/extensions/datacube.py +++ b/pystac/extensions/datacube.py @@ -3,13 +3,15 @@ from __future__ import annotations from abc import ABC -from typing import Any, Generic, Literal, TypeVar, Union, cast +from typing import Any, Generic, Literal, TypeVar, cast import pystac from pystac.extensions.base import ExtensionManagementMixin, PropertiesExtension from pystac.extensions.hooks import ExtensionHooks from pystac.utils import StringEnum, get_required, map_opt +#: Generalized version of :class:`~pystac.Collection`, `:class:`~pystac.Item`, +#: :class:`~pystac.Asset`, or :class:`~pystac.ItemAssetDefinition` T = TypeVar( "T", pystac.Collection, pystac.Item, pystac.Asset, pystac.ItemAssetDefinition ) @@ -523,7 +525,7 @@ def to_dict(self) -> dict[str, Any]: class DatacubeExtension( Generic[T], PropertiesExtension, - ExtensionManagementMixin[Union[pystac.Collection, pystac.Item]], + ExtensionManagementMixin[pystac.Item | pystac.Collection], ): """An abstract class that can be used to extend the properties of a :class:`~pystac.Collection`, :class:`~pystac.Item`, or :class:`~pystac.Asset` with @@ -671,7 +673,7 @@ class AssetDatacubeExtension(DatacubeExtension[pystac.Asset]): in the :stac-ext:`Datacube Extension `. This class should generally not be instantiated directly. Instead, call - :meth:`EOExtension.ext` on an :class:`~pystac.Asset` to extend it. + :meth:`DatacubeExtension.ext` on an :class:`~pystac.Asset` to extend it. """ asset_href: str diff --git a/pystac/extensions/eo.py b/pystac/extensions/eo.py index 58c9b6be5..7d77d8fa8 100644 --- a/pystac/extensions/eo.py +++ b/pystac/extensions/eo.py @@ -9,7 +9,6 @@ Generic, Literal, TypeVar, - Union, cast, ) @@ -25,6 +24,8 @@ from pystac.summaries import RangeSummary from pystac.utils import get_required, map_opt +#: Generalized version of :class:`~pystac.Item`, :class:`~pystac.Asset`, +#: pr :class:`~pystac.ItemAssetDefinition` T = TypeVar("T", pystac.Item, pystac.Asset, pystac.ItemAssetDefinition) SCHEMA_URI: str = "https://stac-extensions.github.io/eo/v1.1.0/schema.json" @@ -289,7 +290,7 @@ def band_description(common_name: str) -> str | None: class EOExtension( Generic[T], PropertiesExtension, - ExtensionManagementMixin[Union[pystac.Item, pystac.Collection]], + ExtensionManagementMixin[pystac.Item | pystac.Collection], ): """An abstract class that can be used to extend the properties of an :class:`~pystac.Item` or :class:`~pystac.Asset` with properties from the @@ -556,9 +557,9 @@ def __init__(self, item_asset: pystac.ItemAssetDefinition): class SummariesEOExtension(SummariesExtension): - """A concrete implementation of :class:`~SummariesExtension` that extends - the ``summaries`` field of a :class:`~pystac.Collection` to include properties - defined in the :stac-ext:`Electro-Optical Extension `. + """A concrete implementation of :class:`~pystac.extensions.base.SummariesExtension` + that extends the ``summaries`` field of a :class:`~pystac.Collection` to include + properties defined in the :stac-ext:`Electro-Optical Extension `. """ @property diff --git a/pystac/extensions/ext.py b/pystac/extensions/ext.py index 9da6b8d4d..5cad55b85 100644 --- a/pystac/extensions/ext.py +++ b/pystac/extensions/ext.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dataclasses import dataclass from typing import Any, Generic, Literal, TypeVar, cast @@ -31,7 +33,11 @@ from pystac.extensions.view import ViewExtension from pystac.extensions.xarray_assets import XarrayAssetsExtension +#: Generalized version of :class:`~pystac.Asset`, +#: :class:`~pystac.ItemAssetDefinition`, or :class:`~pystac.Link` T = TypeVar("T", Asset, ItemAssetDefinition, Link) +#: Generalized version of :class:`~pystac.Asset` or +#: :class:`~pystac.ItemAssetDefinition` U = TypeVar("U", Asset, ItemAssetDefinition) EXTENSION_NAMES = Literal[ @@ -93,15 +99,37 @@ def _get_class_by_name(name: str) -> Any: @dataclass class CatalogExt: + """Supporting the :attr:`~pystac.Catalog.ext` accessor for interacting + with extension classes + """ + stac_object: Catalog def has(self, name: EXTENSION_NAMES) -> bool: + """Whether the given extension is enabled on this STAC object + + Args: + name : Extension identifier (eg: 'eo') + + Returns: + bool: ``True`` if extension is enabled, otherwise ``False`` + """ return cast(bool, _get_class_by_name(name).has_extension(self.stac_object)) def add(self, name: EXTENSION_NAMES) -> None: + """Add the given extension to this STAC object + + Args: + name : Extension identifier (eg: 'eo') + """ _get_class_by_name(name).add_to(self.stac_object) def remove(self, name: EXTENSION_NAMES) -> None: + """Remove the given extension from this STAC object + + Args: + name : Extension identifier (eg: 'eo') + """ _get_class_by_name(name).remove_from(self.stac_object) @property @@ -111,6 +139,10 @@ def version(self) -> VersionExtension[Catalog]: @dataclass class CollectionExt(CatalogExt): + """Supporting the :attr:`~pystac.Collection.ext` accessor for interacting + with extension classes + """ + stac_object: Collection @property @@ -140,15 +172,37 @@ def xarray(self) -> XarrayAssetsExtension[Collection]: @dataclass class ItemExt: + """Supporting the :attr:`~pystac.Item.ext` accessor for interacting + with extension classes + """ + stac_object: Item def has(self, name: EXTENSION_NAMES) -> bool: + """Whether the given extension is enabled on this STAC object + + Args: + name : Extension identifier (eg: 'eo') + + Returns: + bool: ``True`` if extension is enabled, otherwise ``False`` + """ return cast(bool, _get_class_by_name(name).has_extension(self.stac_object)) def add(self, name: EXTENSION_NAMES) -> None: + """Add the given extension to this STAC object + + Args: + name : Extension identifier (eg: 'eo') + """ _get_class_by_name(name).add_to(self.stac_object) def remove(self, name: EXTENSION_NAMES) -> None: + """Remove the given extension from this STAC object + + Args: + name : Extension identifier (eg: 'eo') + """ _get_class_by_name(name).remove_from(self.stac_object) @property @@ -224,10 +278,18 @@ class _AssetsExt(Generic[T]): stac_object: T def has(self, name: EXTENSION_NAMES) -> bool: + """Whether the given extension is enabled on the owner + + Args: + name : Extension identifier (eg: 'eo') + + Returns: + bool: ``True`` if extension is enabled, otherwise ``False`` + """ if self.stac_object.owner is None: raise STACError( - f"Attempted to add extension='{name}' for an object with no owner. " - "Use `.set_owner` and then try to add the extension again." + f"Attempted to use `.ext.has('{name}') for an object with no owner. " + "Use `.set_owner` and then try to check the extension again." ) else: return cast( @@ -235,6 +297,11 @@ def has(self, name: EXTENSION_NAMES) -> bool: ) def add(self, name: EXTENSION_NAMES) -> None: + """Add the given extension to the owner + + Args: + name : Extension identifier (eg: 'eo') + """ if self.stac_object.owner is None: raise STACError( f"Attempted to add extension='{name}' for an object with no owner. " @@ -244,6 +311,11 @@ def add(self, name: EXTENSION_NAMES) -> None: _get_class_by_name(name).add_to(self.stac_object.owner) def remove(self, name: EXTENSION_NAMES) -> None: + """Remove the given extension from the owner + + Args: + name : Extension identifier (eg: 'eo') + """ if self.stac_object.owner is None: raise STACError( f"Attempted to remove extension='{name}' for an object with no owner. " @@ -307,6 +379,10 @@ def view(self) -> ViewExtension[U]: @dataclass class AssetExt(_AssetExt[Asset]): + """Supporting the :attr:`~pystac.Asset.ext` accessor for interacting + with extension classes + """ + stac_object: Asset @property @@ -324,11 +400,19 @@ def xarray(self) -> XarrayAssetsExtension[Asset]: @dataclass class ItemAssetExt(_AssetExt[ItemAssetDefinition]): + """Supporting the :attr:`~pystac.ItemAssetDefinition.ext` accessor for interacting + with extension classes + """ + stac_object: ItemAssetDefinition @dataclass class LinkExt(_AssetsExt[Link]): + """Supporting the :attr:`~pystac.Link.ext` accessor for interacting + with extension classes + """ + stac_object: Link @property diff --git a/pystac/extensions/file.py b/pystac/extensions/file.py index baae567a5..c6e24bd91 100644 --- a/pystac/extensions/file.py +++ b/pystac/extensions/file.py @@ -4,7 +4,7 @@ import warnings from collections.abc import Iterable -from typing import Any, Generic, Literal, TypeVar, Union, cast +from typing import Any, Generic, Literal, TypeVar, cast from pystac import ( Asset, @@ -24,6 +24,7 @@ ) from pystac.utils import StringEnum, get_required, map_opt +#: Generalized version of :class:`~pystac.Asset`, :class:`~pystac.Link`, T = TypeVar("T", Asset, Link) SCHEMA_URI = "https://stac-extensions.github.io/file/v2.1.0/schema.json" @@ -106,7 +107,7 @@ def to_dict(self) -> dict[str, Any]: class FileExtension( Generic[T], PropertiesExtension, - ExtensionManagementMixin[Union[Catalog, Collection, Item]], + ExtensionManagementMixin[Catalog | Collection | Item], ): """A class that can be used to extend the properties of an :class:`~pystac.Asset` or :class:`~pystac.Link` with properties from the diff --git a/pystac/extensions/grid.py b/pystac/extensions/grid.py index 5b3404b8b..9640a2c7f 100644 --- a/pystac/extensions/grid.py +++ b/pystac/extensions/grid.py @@ -5,7 +5,7 @@ import re import warnings from re import Pattern -from typing import Any, Literal, Union +from typing import Any, Literal import pystac from pystac.extensions.base import ExtensionManagementMixin, PropertiesExtension @@ -37,14 +37,16 @@ def validated_code(v: str) -> str: class GridExtension( PropertiesExtension, - ExtensionManagementMixin[Union[pystac.Item, pystac.Collection]], + ExtensionManagementMixin[pystac.Item | pystac.Collection], ): - """A concrete implementation of :class:`GridExtension` on an :class:`~pystac.Item` + """A concrete implementation of :class:`~pystac.extensions.grid.GridExtension` + on an :class:`~pystac.Item` that extends the properties of the Item to include properties defined in the :stac-ext:`Grid Extension `. This class should generally not be instantiated directly. Instead, call - :meth:`GridExtension.ext` on an :class:`~pystac.Item` to extend it. + :meth:`~pystac.extensions.grid.GridExtension.ext` on an :class:`~pystac.Item` + to extend it. .. code-block:: python diff --git a/pystac/extensions/label.py b/pystac/extensions/label.py index 0a75f4470..c8595413e 100644 --- a/pystac/extensions/label.py +++ b/pystac/extensions/label.py @@ -4,7 +4,7 @@ import warnings from collections.abc import Iterable, Sequence -from typing import Any, Literal, Union, cast +from typing import Any, Literal, cast import pystac from pystac.extensions.base import ExtensionManagementMixin, SummariesExtension @@ -440,7 +440,7 @@ def __eq__(self, o: object) -> bool: return self.to_dict() == o -class LabelExtension(ExtensionManagementMixin[Union[pystac.Item, pystac.Collection]]): +class LabelExtension(ExtensionManagementMixin[pystac.Item | pystac.Collection]): """A class that can be used to extend the properties of an :class:`~pystac.Item` with properties from the :stac-ext:`Label Extension