Exemplo n.º 1
0
    def test_validate_examples(self) -> None:
        for example in TestCases.get_examples_info():
            with self.subTest(example.path):
                stac_version = example.stac_version
                path = example.path
                valid = example.valid

                with self.subTest(path):
                    with open(path, encoding="utf-8") as f:
                        stac_json = json.load(f)

                    # Check if common properties need to be merged
                    if stac_version < "1.0":
                        if example.object_type == pystac.STACObjectType.ITEM:
                            collection_cache = CollectionCache()
                            merge_common_properties(stac_json,
                                                    collection_cache, path)

                    if valid:
                        pystac.validation.validate_dict(stac_json)
                    else:
                        with self.assertRaises(pystac.STACValidationError):
                            try:
                                pystac.validation.validate_dict(stac_json)
                            except pystac.STACValidationError as e:
                                self.assertIsInstance(
                                    e.source, jsonschema.ValidationError)
                                raise e
Exemplo n.º 2
0
    def test_validate_examples(self):
        for example in TestCases.get_examples_info():
            stac_version = example['stac_version']
            path = example['path']
            valid = example['valid']

            if stac_version < '0.8':
                with open(path) as f:
                    stac_json = json.load(f)

                self.assertEqual(
                    len(pystac.validation.validate_dict(stac_json)), 0)
            else:
                with self.subTest(path):
                    with open(path) as f:
                        stac_json = json.load(f)

                    # Check if common properties need to be merged
                    if stac_version < '1.0':
                        if example[
                                'object_type'] == pystac.STACObjectType.ITEM:
                            collection_cache = pystac.cache.CollectionCache()
                            merge_common_properties(stac_json,
                                                    collection_cache, path)

                    if valid:
                        pystac.validation.validate_dict(stac_json)
                    else:
                        with self.assertRaises(STACValidationError):
                            try:
                                pystac.validation.validate_dict(stac_json)
                            except STACValidationError as e:
                                self.assertIsInstance(
                                    e.source, jsonschema.ValidationError)
                                raise e
Exemplo n.º 3
0
def stac_object_from_dict(d, href=None, root=None):
    """Determines how to deserialize a dictionary into a STAC object.

    Args:
        d (dict): The dict to parse.
        href (str): Optional href that is the file location of the object being
            parsed.
        root (Catalog or Collection): 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.

    Note: This is used internally in STAC_IO to deserialize STAC Objects.
    It is in the top level __init__ in order to avoid circular dependencies.
    """
    if identify_stac_object_type(d) == STACObjectType.ITEM:
        collection_cache = None
        if root is not None:
            collection_cache = root._resolved_objects.as_collection_cache()

        merge_common_properties(d, json_href=href, collection_cache=collection_cache)

    info = identify_stac_object(d)

    d = migrate_to_latest(d, info)

    if info.object_type == STACObjectType.CATALOG:
        return Catalog.from_dict(d, href=href, root=root)

    if info.object_type == STACObjectType.COLLECTION:
        return Collection.from_dict(d, href=href, root=root)

    if info.object_type == STACObjectType.ITEMCOLLECTION:
        if Extension.SINGLE_FILE_STAC in info.common_extensions:
            return SingleFileSTAC.from_dict(d, href=href, root=root)

        return ItemCollection.from_dict(d, href=href, root=root)

    if info.object_type == STACObjectType.ITEM:
        if Extension.EO in info.common_extensions:
            return EOItem.from_dict(d, href=href, root=root)

        if Extension.LABEL in info.common_extensions:
            return LabelItem.from_dict(d, href=href, root=root)

        return Item.from_dict(d, href=href, root=root)
Exemplo n.º 4
0
def identify_stac_object(json_dict,
                         merge_collection_properties=False,
                         json_href=None,
                         collection_cache=None):
    """Determines the STACJSONDescription of the provided JSON dict.

    Args:
        json_dict (dict): The dict of STAC JSON to identify.
        merge_collection_properties (bool): If True, follow the collection links
            in Items if required to discover extensions and version (pre-0.8 STAC).
            Defaults to False.
        json_href (str): The path that this JSON came from. This is useful for
            for resolving relative paths to Collections in the case that
            ``merge_collection_properties`` is True and the collection link
            is relative.
        collection_cache (dict): If supplied, collection read for item links
            will check this cache for either the collection's ID (if available)
            or the HREF of the collection link. This is recommended to reduce
            unnecessary re-reading of collections.

    Returns:
        STACJSONDescription: The description of the STAC object serialized in the
        given dict.

    Note:
        If ``merge_collection_properties`` is False, there are cases where the
        common_extensions returned could be incorrect - e.g. if a collection lists
        'eo' extension properties but the Item does not contian any properties with
        the 'eo:' prefix.
    """
    object_type = identify_stac_object_type(json_dict)

    version_range = STACVersionRange()

    stac_version = json_dict.get('stac_version')
    stac_extensions = json_dict.get('stac_extensions', None)

    if stac_version is None:
        if object_type == STACObjectType.CATALOG or object_type == STACObjectType.COLLECTION:
            version_range.set_max('0.5.2')
        elif object_type == STACObjectType.ITEM:
            version_range.set_max('0.7.0')
        else:  # ItemCollection
            version_range.set_min('0.8.0')
    else:
        version_range.set_to_single(stac_version)

    if stac_extensions is None:
        # If this is post-0.8, we can assume there are no extensions
        # if the stac_extensions property doesn't exist for everything
        # but ItemCollection.
        if version_range.min_version is None or \
           version_range.min_version < '0.8.0' or \
           object_type == STACObjectType.ITEMCOLLECTION:
            if merge_collection_properties and object_type == STACObjectType.ITEM:
                merge_common_properties(json_dict, collection_cache, json_href)

            stac_extensions = _identify_stac_extensions(
                object_type, json_dict, version_range)
        else:
            stac_extensions = []

    if not version_range.is_single_version():
        # Final Checks

        # self links became non-required in 0.7.0
        if 'links' in json_dict:
            if not any(filter(lambda l: l['rel'] == 'self',
                              json_dict['links'])):
                version_range.set_min('0.7.0')

        # links were a dictionary only in 0.5
        if 'links' in json_dict and isinstance(json_dict['links'], dict):
            version_range.set_to_single('0.5.2')

    common_extensions, custom_extensions = _split_extensions(stac_extensions)

    return STACJSONDescription(object_type, version_range, common_extensions,
                               custom_extensions)