<jupyter_start><jupyter_text>Reading Data from the STAC APIThe Planetary Computer catalogs the datasets we host using the [STAC](http://stacspec.org/) (SpatiaoTemporal Asset Catalog) specification. We provide a [STAC API](https://github.com/radiantearth/stac-api-spec) endpoint that can be used to search our datasets by space, time, and more. This quickstart will show you how to search for data using our STAC API and open-source Python libraries. For more on how to use our STAC API from R, see [Reading data from the STAC API with R](https://planetarycomputer.microsoft.com/docs/quickstarts/reading-stac-r/).To get started you'll need the [pystac-client](https://github.com/stac-utils/pystac-client) library installed. You can install it via pip:```> pip install pystac-client```First we'll use pystac-client to open up our STAC API:<jupyter_code>from pystac_client import Client

catalog = Client.open("https://planetarycomputer.microsoft.com/api/stac/v1")<jupyter_output><empty_output><jupyter_text>SearchingWe can use the STAC API to search for assets meeting some criteria. This might include the date and time the asset covers, is spatial extent, or any other property captured in the STAC item's metadata.In this example we'll search for imagery from [Landsat Collection 2 Level-2](https://planetarycomputer.microsoft.com/dataset/landsat-8-c2-l2) area around Microsoft's main campus in December of 2020.<jupyter_code>time_range = "2020-12-01/2020-12-31"
bbox = [-122.2751, 47.5469, -121.9613, 47.7458]

search = catalog.search(collections=["landsat-8-c2-l2"], bbox=bbox, datetime=time_range)
items = search.get_all_items()
len(items)<jupyter_output><empty_output><jupyter_text>In that example our spatial query used a bounding box with a `bbox`. Alternatively, you can pass a GeoJSON object as `intersects````pythonarea_of_interest = {    "type": "Polygon",    "coordinates": [        [            [-122.2751, 47.5469],            [-121.9613, 47.9613],            [-121.9613, 47.9613],            [-122.2751, 47.9613],            [-122.2751, 47.5469],        ]    ],}time_range = "2020-12-01/2020-12-31"search = catalog.search(    collections=["landsat-8-c2-l2"], intersects=area_of_interest, datetime=time_range)``` `items` is a [`pystac.ItemCollection`](https://pystac.readthedocs.io/en/stable/api/item_collection.htmlpystac-item-collection). We can see that 4 items matched our search criteria.<jupyter_code>len(items)<jupyter_output><empty_output><jupyter_text>Each [`pystac.Item`](https://pystac.readthedocs.io/en/stable/api/pystac.htmlpystac.Item) in this `ItemCollection` includes all the metadata for that scene. [STAC Items](https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md) are GeoJSON features, and so can be loaded by libraries like [geopandas](http://geopandas.readthedocs.io/).<jupyter_code>import geopandas

df = geopandas.GeoDataFrame.from_features(items.to_dict(), crs="epsg:4326")
df<jupyter_output><empty_output><jupyter_text>We can use the `eo` extension to sort the items by cloudiness. We'll grab an item with low cloudiness:<jupyter_code>selected_item = min(items, key=lambda item: item.properties["eo:cloud_cover"])
selected_item<jupyter_output><empty_output><jupyter_text>Each STAC item has one or more [Assets](https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.mdasset-object), which include links to the actual files.<jupyter_code>import rich.table

table = rich.table.Table("Asset Key", "Descripiption")
for asset_key, asset in selected_item.assets.items():
    # print(f"{asset_key:<25} - {asset.title}")
    table.add_row(asset_key, asset.title)

table<jupyter_output><empty_output><jupyter_text>Here, we'll inspect the `rendered_preview` asset.<jupyter_code>selected_item.assets["rendered_preview"].to_dict()
from IPython.display import Image

Image(url=selected_item.assets["rendered_preview"].href, width=500)<jupyter_output><empty_output><jupyter_text>That `rendered_preview` asset is generated dynamically from the raw data using the Planetary Computer's [data API](http://planetarycomputer.microsoft.com/api/data/v1/). We can access the raw data, stored as Cloud Optimzied GeoTIFFs in Azure Blob Storage, using one of the other assets. That said, we do need to do one more thing before accessing the data. If we simply made a request to the file in blob storage we'd get a 404:<jupyter_code>import requests

url = selected_item.assets["SR_B2"].href
print("Accessing", url)
response = requests.get(url)
response<jupyter_output>Accessing https://landsateuwest.blob.core.windows.net/landsat-c2/level-2/standard/oli-tirs/2020/047/027/LC08_L2SP_047027_20201204_20210313_02_T1/LC08_L2SP_047027_20201204_20210313_02_T1_SR_B2.TIF<jupyter_text>That's because the Plantary Computer uses Azure Blob Storage [SAS Tokens](https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overviewhow-a-shared-access-signature-works) to enable access to our data, which allows us to provide the data for free to anyone, anywhere while maintaining some control over the amount of egress for datasets.To get a token for access, you can use the Planetary Computer's [Data Authentication API](../reference/sas.md). You can access that anonymously, or you can provide an API Key for higher rate limits and longer-lived tokens.You can also use the [planetary-computer](https://github.com/microsoft/planetary-computer-sdk-for-python) package to generate tokens and sign asset HREFs for access. You can install via pip with```> pip install planetary-computer```<jupyter_code>import planetary_computer

# PC_SDK_SUBSCRIPTION_KEY
signed_href = planetary_computer.sign(selected_item).assets["SR_B2"].href<jupyter_output><empty_output><jupyter_text>We can load up that single COG using libraries like [rioxarray](https://corteva.github.io/rioxarray/html/rioxarray.html) or [rasterio](https://rasterio.readthedocs.io/en/latest/)<jupyter_code># import xarray as xr
import rioxarray

ds = rioxarray.open_rasterio(signed_href, overview_level=4).squeeze()
img = ds.plot(cmap="Blues", add_colorbar=False)
img.axes.set_axis_off();<jupyter_output><empty_output><jupyter_text>If you wish to work with multiple STAC items as a datacube, you can use libraries like [stackstac](https://stackstac.readthedocs.io/) or [odc-stac](https://odc-stac.readthedocs.io/en/latest/index.html).<jupyter_code>import stackstac

ds = stackstac.stack(planetary_computer.sign(items))
ds<jupyter_output><empty_output><jupyter_text>Searching on additional propertiesPreviously, we searched for items by space and time. Because the Planetary Computer's STAC API supports the [query](https://github.com/radiantearth/stac-api-spec/blob/master/fragments/query/README.md) parameter, you can search on additional properties on the STAC item.For example, collections like `sentinel-2-l2a` and `landsat-8-c2-l2` both implement the [`eo` STAC extension](https://github.com/stac-extensions/eo) and include an `eo:cloud_cover` property. Use `query={"eo:cloud_cover": {"lt": 20}}` to return only items that are less than 20% cloudy.<jupyter_code>time_range = "2020-12-01/2020-12-31"
bbox = [-122.2751, 47.5469, -121.9613, 47.7458]

search = catalog.search(
    collections=["sentinel-2-l2a"],
    bbox=bbox,
    datetime=time_range,
    query={"eo:cloud_cover": {"lt": 20}},
)
items = search.get_all_items()<jupyter_output><empty_output><jupyter_text>Other common uses of the `query` parameter is to filter a collection down to items of a specific type, For example, the [GOES-CMI](https://planetarycomputer.microsoft.com/dataset/goes-cmi) collection includes images from various when the satellite is in various modes, which produces images of either the Full Disk of the earth, the continental United States, or a mesoscale. You can use `goes:image-type` to filter down to just the ones you want.<jupyter_code>search = catalog.search(
    collections=["goes-cmi"],
    bbox=[-67.2729, 25.6000, -61.7999, 27.5423],
    datetime=["2018-09-11T13:00:00Z", "2018-09-11T15:40:00Z"],
    query={"goes:image-type": {"eq": "MESOSCALE"}},
)<jupyter_output><empty_output><jupyter_text>Analyzing STAC MetadataSTAC items are proper GeoJSON Features, and so can be treated as a kind of data on their own.<jupyter_code>search = catalog.search(
    collections=["sentinel-2-l2a"],
    bbox=[-124.2751, 45.5469, -110.9613, 47.7458],
    datetime="2020-12-26/2020-12-31",
)
items = search.get_all_items()

df = geopandas.GeoDataFrame.from_features(items.to_dict(), crs="epsg:4326")

df[["geometry", "datetime", "s2:mgrs_tile", "eo:cloud_cover"]].explore(
    column="eo:cloud_cover", style_kwds={"fillOpacity": 0.1}
)<jupyter_output><empty_output><jupyter_text>Or we can plot cloudiness of a region over time.<jupyter_code>import pandas as pd

search = catalog.search(
    collections=["sentinel-2-l2a"],
    bbox=[-124.2751, 45.5469, -123.9613, 45.7458],
    datetime="2020-01-01/2020-12-31",
)
items = search.get_all_items()
df = geopandas.GeoDataFrame.from_features(items.to_dict())
df["datetime"] = pd.to_datetime(df["datetime"])
ts = df.set_index("datetime").sort_index()["eo:cloud_cover"].rolling(7).mean()
ts.plot(title="eo:cloud-cover (7-scene rolling average)");<jupyter_output><empty_output><jupyter_text>Working with STAC Catalogs and CollectionsOur `catalog` is a [STAC Catalog](https://github.com/radiantearth/stac-spec/blob/master/catalog-spec/catalog-spec.md) that we can crawl or search. The Catalog contains [STAC Collections](https://github.com/radiantearth/stac-spec/blob/master/collection-spec/collection-spec.md) for each dataset we have indexed (which is not the yet the entirity of data hosted by the Planetary Computer).Collections have information about the [STAC Items](https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md) they contain. For instance, here we look at the [Bands](https://github.com/stac-extensions/eoband-object) available for [Landsat 8 Collection 2 Level 2](https://planetarycomputer.microsoft.com/dataset/landsat-8-c2-l2) data:<jupyter_code>import pandas as pd

landsat = catalog.get_collection("landsat-8-c2-l2")

pd.DataFrame(landsat.extra_fields["summaries"]["eo:bands"])<jupyter_output><empty_output><jupyter_text>We can see what [Assets](https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.mdasset-object) are available on our item with:<jupyter_code>pd.DataFrame.from_dict(landsat.extra_fields["item_assets"], orient="index")[
    ["title", "description", "gsd"]
]<jupyter_output><empty_output><jupyter_text>Some collections, like [Daymet](https://planetarycomputer.microsoft.com/dataset/daymet-daily-na) include collection-level assets. You can use the `.assets` property to access those assets.<jupyter_code>collection = catalog.get_collection("daymet-daily-na")
collection<jupyter_output><empty_output><jupyter_text>Just like assets on items, these assets include links to data in Azure Blob Storage.<jupyter_code>asset = collection.assets["zarr-https"]
asset
import fsspec
import xarray as xr

store = fsspec.get_mapper(asset.href)
ds = xr.open_zarr(store, **asset.extra_fields["xarray:open_kwargs"])
ds<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12442809724589576, 'fraction_numerical': 0.039293083340809186, 'mean_word_length': 5.839263803680981, 'pattern_counts': {'":': 9, '<': 77, '<?xml version=': 0, '>': 78, 'https://': 26, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '19', 'dir': 'jupyter-structured-clean-dedup', 'id': '54014', 'license': 'MIT', 'n_tokens_mistral': 4023, 'n_tokens_neox': 3683, 'n_words': 906, 'path': 'quickstarts/reading-stac.ipynb', 'repo_name': 'RadiantMLHub/PlanetaryComputerExamples', 'size': '11147'}