def test_no_stac_core_conformance(self):
        """Should raise a ConformanceError if the API does not conform to the STAC API - Core spec."""
        api_content = read_data_file('astraea_api.json', parse_json=True)

        # Remove "conformsTo" attribute
        api_content['conformsTo'] = []

        with pytest.raises(ConformanceError):
            Client.from_dict(api_content)
    def test_no_conformance(self):
        """Should raise a KeyError if no conformance info can be found. Luckily, the test API doesn't publish
        a "conformance" link so we can just remove the "conformsTo" attribute to test this."""
        api_content = read_data_file('astraea_api.json', parse_json=True)

        # Remove "conformsTo" attribute
        del api_content['conformsTo']

        with pytest.raises(KeyError):
            Client.from_dict(api_content)
 def test_no_url(self):
     old_stac_url = os.environ.get("STAC_URL")
     if old_stac_url:
         del os.environ["STAC_URL"]
     try:
         with pytest.raises(TypeError):
             Client.open()
     finally:
         if old_stac_url:
             os.environ["STAC_URL"] = old_stac_url
    def test_instance(self):
        api = Client.from_file(ASTRAEA_API_PATH)

        # An API instance is also a Catalog instance
        assert isinstance(api, pystac.Catalog)

        assert str(api) == '<Catalog id=astraea>'
    def test_links(self):
        api = Client.from_file(ASTRAEA_API_PATH)

        # Should be able to get collections via links as with a typical PySTAC Catalog
        collection_links = api.get_links('child')
        assert len(collection_links) > 0

        first_collection = api.get_single_link('child').resolve_stac_object(
            root=api).target
        assert isinstance(first_collection, pystac.Collection)
 def test_environment_variable(self):
     old_stac_url = os.environ.get("STAC_URL")
     os.environ["STAC_URL"] = ASTRAEA_URL
     try:
         client = Client.open()
         assert client.title == "Astraea Earth OnDemand"
     finally:
         if old_stac_url:
             os.environ["STAC_URL"] = old_stac_url
         else:
             del os.environ["STAC_URL"]
Exemple #7
0
def stac_api_to_odc(
    dc: Datacube,
    update_if_exists: bool,
    config: dict,
    catalog_href: str,
    allow_unsafe: bool = True,
    rewrite: Optional[Tuple[str, str]] = None,
) -> Tuple[int, int]:
    doc2ds = Doc2Dataset(dc.index)
    client = Client.open(catalog_href)

    search = client.search(**config)
    n_items = search.matched()
    if n_items is not None:
        logging.info("Found {} items to index".format(n_items))
        if n_items == 0:
            logging.warning("Didn't find any items, finishing.")
            return 0, 0
    else:
        logging.warning("API did not return the number of items.")

    # Do the indexing of all the things
    success = 0
    failure = 0

    sys.stdout.write("\rIndexing from STAC API...\n")
    with concurrent.futures.ThreadPoolExecutor(max_workers=50) as executor:
        future_to_item = {
            executor.submit(
                process_item,
                item,
                dc,
                doc2ds,
                update_if_exists=update_if_exists,
                allow_unsafe=allow_unsafe,
                rewrite=rewrite,
            ): item.id
            for item in search.get_all_items()
        }
        for future in concurrent.futures.as_completed(future_to_item):
            item = future_to_item[future]
            try:
                _ = future.result()
                success += 1
                if success % 10 == 0:
                    sys.stdout.write(f"\rAdded {success} datasets...")
            except Exception as e:
                logging.exception(f"Failed to handle item {item} with exception {e}")
                failure += 1
    sys.stdout.write("\r")

    return success, failure
    def query_geom(self, geom_idx):
        geom = self.geoms[geom_idx]
        catalog = Client.open(
            "https://planetarycomputer.microsoft.com/api/stac/v1")

        search = catalog.search(
            collections=["sentinel-2-l2a"],
            intersects=geom,
            datetime=self.time_range,
            query={"eo:cloud_cover": {
                "lt": 10
            }},
        )

        items = list(search.get_items())
        return items[::-1]
    def test_legacy_conformance(self):
        """APIs publishing legacy conformance URIs should pass when tested against a ConformanceClass, but
        fail when tested against the official URI string"""
        api_content = read_data_file('astraea_api.json', parse_json=True)

        # Set conformsTo URIs to conform with STAC API - Core using official URI
        api_content['conformsTo'] = [
            'http://stacspec.org/spec/api/1.0.0-beta.1/core'
        ]
        api = Client.from_dict(api_content)

        # Must have a conformance property that is the list of URIs from the conformsTo property
        assert hasattr(api, 'conformance')
        assert api.conformance == api_content['conformsTo']

        assert api.conforms_to(ConformanceClasses.STAC_API_CORE)

        assert not api.conforms_to(
            'https://api.stacspec.org/v1.0.0-beta.1/core')
Exemple #10
0
    def test_spec_conformance(self):
        """Testing conformance against a ConformanceClass should allow APIs using legacy URIs to pass."""
        api_content = read_data_file('astraea_api.json', parse_json=True)

        # Set conformsTo URIs to conform with STAC API - Core using official URI
        api_content['conformsTo'] = [
            'https://api.stacspec.org/v1.0.0-beta.1/core'
        ]
        api = Client.from_dict(api_content)

        # Must have a conformance property that is the list of URIs from the conformsTo property
        assert hasattr(api, 'conformance')
        assert api.conformance == api_content['conformsTo']

        # Check the conformance to STAC API - Core using the ConformanceClass
        assert api.conforms_to(ConformanceClasses.STAC_API_CORE)

        # ... and using a URI string
        assert api.conforms_to('https://api.stacspec.org/v1.0.0-beta.1/core')
Exemple #11
0
 def api(self):
     return Client.from_file(str(TEST_DATA / 'astraea_api.json'))
Exemple #12
0
    def test_from_file(self):
        api = Client.from_file(ASTRAEA_URL)

        assert api.title == 'Astraea Earth OnDemand'
Exemple #13
0
        validate_core(root_body, warnings, errors)
    else:
        errors.append(
            "/ : 'conformsTo' must contain STAC API - Core conformance class.")

    if any(oaf_cc_regex.fullmatch(x) for x in conforms_to):
        print("STAC API - Features conformance class found.")
        validate_oaf(root_body, warnings, errors)

    if any(search_cc_regex.fullmatch(x) for x in conforms_to):
        print("STAC API - Item Search conformance class found.")
        validate_search(root_body, post, conforms_to, warnings, errors)

    if not errors:
        try:
            catalog = Client.open(root_url)
            catalog.validate()
            for collection in catalog.get_children():
                collection.validate()
        except STACValidationError as e:
            errors.append(f"pystac error: {str(e)}")

    return warnings, errors


def href_for(links: List, key: str) -> Dict[str, str]:
    return next((link for link in links if link.get("rel") == key), None)


def validate_core(root_body: Dict, warnings: List[str],
                  errors: List[str]) -> None:
 def astraea_api(self):
     api_content = read_data_file('astraea_api.json', parse_json=True)
     return Client.from_dict(api_content)
Exemple #15
0
 def api(self):
     return Client.from_file(ASTRAEA_API_PATH)