# Source code for pystac

    # isort: skip_file
    """
    PySTAC is a library for working with SpatioTemporal Asset Catalogs (STACs)
    """
    __all__ = [
        "__version__",
        "TemplateError",
        "STACError",
        "STACTypeError",
        "DuplicateObjectKeyError",
        "ExtensionAlreadyExistsError",
        "ExtensionNotImplemented",
        "ExtensionTypeError",
        "RequiredPropertyMissing",
        "STACValidationError",
        "DeprecatedWarning",
        "MediaType",
        "RelType",
        "StacIO",
        "STACObject",
        "STACObjectType",
        "Link",
        "HIERARCHICAL_LINKS",
        "Catalog",
        "CatalogType",
        "Collection",
        "Extent",
        "SpatialExtent",
        "TemporalExtent",
        "Summaries",
        "CommonMetadata",
        "RangeSummary",
        "Item",
        "Asset",
        "ItemCollection",
        "Provider",
        "ProviderRole",
        "read_file",
        "read_dict",
        "write_file",
        "get_stac_version",
        "set_stac_version",
    ]

    import os
    import warnings
    from typing import Any, Optional

    from pystac.errors import (
        TemplateError,
        STACError,
        STACTypeError,
        DuplicateObjectKeyError,
        ExtensionAlreadyExistsError,
        ExtensionNotImplemented,
        ExtensionTypeError,
        RequiredPropertyMissing,
        STACValidationError,
        DeprecatedWarning,
    )

    from pystac.version import (
        __version__,
        get_stac_version,
        set_stac_version,
    )
    from pystac.media_type import MediaType
    from pystac.rel_type import RelType
    from pystac.stac_io import StacIO
    from pystac.stac_object import STACObject, STACObjectType
    from pystac.link import Link, HIERARCHICAL_LINKS
    from pystac.catalog import Catalog, CatalogType
    from pystac.collection import (
        Collection,
        Extent,
        SpatialExtent,
        TemporalExtent,
    )
    from pystac.common_metadata import CommonMetadata
    from pystac.summaries import RangeSummary, Summaries
    from pystac.asset import Asset
    from pystac.item import Item
    from pystac.item_collection import ItemCollection
    from pystac.provider import ProviderRole, Provider
    from pystac.utils import HREF
    import pystac.validation

    import pystac.extensions.hooks
    import pystac.extensions.classification
    import pystac.extensions.datacube
    import pystac.extensions.eo
    import pystac.extensions.file
    import pystac.extensions.grid
    import pystac.extensions.item_assets

    with warnings.catch_warnings():
        warnings.filterwarnings("ignore", category=DeprecationWarning)
        import pystac.extensions.label
    import pystac.extensions.mgrs
    import pystac.extensions.pointcloud
    import pystac.extensions.projection
    import pystac.extensions.raster
    import pystac.extensions.sar
    import pystac.extensions.sat
    import pystac.extensions.scientific
    import pystac.extensions.storage
    import pystac.extensions.table
    import pystac.extensions.timestamps
    import pystac.extensions.version
    import pystac.extensions.view
    import pystac.extensions.xarray_assets

    EXTENSION_HOOKS = pystac.extensions.hooks.RegisteredExtensionHooks(
        [
            pystac.extensions.classification.CLASSIFICATION_EXTENSION_HOOKS,
            pystac.extensions.datacube.DATACUBE_EXTENSION_HOOKS,
            pystac.extensions.eo.EO_EXTENSION_HOOKS,
            pystac.extensions.file.FILE_EXTENSION_HOOKS,
            pystac.extensions.grid.GRID_EXTENSION_HOOKS,
            pystac.extensions.item_assets.ITEM_ASSETS_EXTENSION_HOOKS,
            pystac.extensions.label.LABEL_EXTENSION_HOOKS,
            pystac.extensions.mgrs.MGRS_EXTENSION_HOOKS,
            pystac.extensions.pointcloud.POINTCLOUD_EXTENSION_HOOKS,
            pystac.extensions.projection.PROJECTION_EXTENSION_HOOKS,
            pystac.extensions.raster.RASTER_EXTENSION_HOOKS,
            pystac.extensions.sar.SAR_EXTENSION_HOOKS,
            pystac.extensions.sat.SAT_EXTENSION_HOOKS,
            pystac.extensions.scientific.SCIENTIFIC_EXTENSION_HOOKS,
            pystac.extensions.storage.STORAGE_EXTENSION_HOOKS,
            pystac.extensions.table.TABLE_EXTENSION_HOOKS,
            pystac.extensions.timestamps.TIMESTAMPS_EXTENSION_HOOKS,
            pystac.extensions.version.VERSION_EXTENSION_HOOKS,
            pystac.extensions.view.VIEW_EXTENSION_HOOKS,
            pystac.extensions.xarray_assets.XARRAY_ASSETS_EXTENSION_HOOKS,
        ]
    )

    def read_file(href: HREF, stac_io: Optional[StacIO] = None) -> STACObject:
        """Reads a STAC object from a file.

        This method will return either a Catalog, a Collection, or an Item based on what
        the file contains.

        This is a convenience method for :meth:`StacIO.read_stac_object
        <pystac.StacIO.read_stac_object>`

        Args:
            href : The HREF to read the object from.
            stac_io: Optional :class:`~StacIO` instance to use for I/O operations. If not
                provided, will use :meth:`StacIO.default` to create an instance.

        Returns:
            The specific STACObject implementation class that is represented
            by the JSON read from the file located at HREF.

        Raises:
            STACTypeError : If the file at ``href`` does not represent a valid
                :class:`~pystac.STACObject`. Note that an :class:`~pystac.ItemCollection`
                is not a :class:`~pystac.STACObject` and must be read using
                :meth:`ItemCollection.from_file <pystac.ItemCollection.from_file>`
        """
        if stac_io is None:
            stac_io = StacIO.default()
        return stac_io.read_stac_object(href)

    def write_file(
        obj: STACObject,
        include_self_link: bool = True,
        dest_href: Optional[HREF] = None,
        stac_io: Optional[StacIO] = None,
    ) -> None:
        """Writes a STACObject to a file.

        This will write only the Catalog, Collection or Item ``obj``. It will not attempt
        to write any other objects that are linked to ``obj``; if you'd like functionality
        to save off catalogs recursively see :meth:`Catalog.save <pystac.Catalog.save>`.

        This method will write the JSON of the object to the object's assigned "self" link
        or to the dest_href if provided. To set the self link, see
        :meth:`STACObject.set_self_href <pystac.STACObject.set_self_href>`.

        Convenience method for :meth:`STACObject.from_file <pystac.STACObject.from_file>`

        Args:
            obj : The STACObject to save.
            include_self_link : If ``True``, include the ``"self"`` link with this object.
                Otherwise, leave out the self link.
            dest_href : Optional HREF to save the file to. If ``None``, the object will be
                saved to the object's ``"self"`` href.
            stac_io: Optional :class:`~StacIO` instance to use for I/O operations. If not
                provided, will use :meth:`StacIO.default` to create an instance.
        """
        if stac_io is None:
            stac_io = StacIO.default()
        dest_href = None if dest_href is None else str(os.fspath(dest_href))
        obj.save_object(
            include_self_link=include_self_link, dest_href=dest_href, stac_io=stac_io
        )

    def read_dict(
        d: dict[str, Any],
        href: Optional[str] = None,
        root: Optional[Catalog] = None,
        stac_io: Optional[StacIO] = None,
    ) -> STACObject:
        """Reads a :class:`~STACObject` or :class:`~ItemCollection` from a JSON-like dict
        representing a serialized STAC object.

        This method will return either a :class:`~Catalog`, :class:`~Collection`,
        or :class`~Item` based on the contents of the dict.

        This is a convenience method for either
        :meth:`StacIO.stac_object_from_dict <pystac.StacIO.stac_object_from_dict>`.

        Args:
            d : The dict to parse.
            href : Optional href that is the file location of the object being
                parsed.
            root : Optional root of the catalog for this object.
                If provided, the root's resolved object cache can be used to search for
                previously resolved instances of the STAC object.
            stac_io: Optional :class:`~StacIO` instance to use for reading. If ``None``,
                the default instance will be used.

        Raises:
            STACTypeError : If the ``d`` dictionary does not represent a valid
                :class:`~pystac.STACObject`. Note that an :class:`~pystac.ItemCollection`
                is not a :class:`~pystac.STACObject` and must be read using
                :meth:`ItemCollection.from_dict <pystac.ItemCollection.from_dict>`
        """
        if stac_io is None:
            stac_io = StacIO.default()
        return stac_io.stac_object_from_dict(d, href, root)