PySTAC-Client Introduction#

This notebook shows basic use of pystac-client to open an API, iterate through Collections and Items, and perform simple spatio-temporal searches.

[1]:
from pystac_client import Client

# set pystac_client logger to DEBUG to see API calls
import logging
logging.basicConfig()
logger = logging.getLogger('pystac_client')
logger.setLevel(logging.DEBUG)

Client#

We first connect to an API by retrieving the root catalog, or landing page, of the API with the Client.open function.

[2]:
# STAC API root URL
URL = 'https://planetarycomputer.microsoft.com/api/stac/v1'

# custom headers
headers = []

cat = Client.open(URL, headers=headers)
cat
DEBUG:pystac_client.stac_api_io:GET https://planetarycomputer.microsoft.com/api/stac/v1 Headers: {'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
[2]:

CollectionClient#

As with a static catalog the get_collections function will iterate through the Collections in the Catalog. Notice that because this is an API it can get all the Collections through a single call, rather than having to fetch each one individually.

[3]:
for collection in cat.get_collections():
    print(collection)
DEBUG:pystac_client.stac_api_io:GET https://planetarycomputer.microsoft.com/api/stac/v1/ Headers: {'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
DEBUG:pystac_client.stac_api_io:GET https://planetarycomputer.microsoft.com/api/stac/v1/collections Headers: {'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
<CollectionClient id=daymet-annual-pr>
<CollectionClient id=daymet-daily-hi>
<CollectionClient id=3dep-seamless>
<CollectionClient id=3dep-lidar-dsm>
<CollectionClient id=fia>
<CollectionClient id=sentinel-1-rtc>
<CollectionClient id=gridmet>
<CollectionClient id=daymet-annual-na>
<CollectionClient id=daymet-monthly-na>
<CollectionClient id=daymet-annual-hi>
<CollectionClient id=daymet-monthly-hi>
<CollectionClient id=daymet-monthly-pr>
<CollectionClient id=gnatsgo-tables>
<CollectionClient id=hgb>
<CollectionClient id=cop-dem-glo-30>
<CollectionClient id=cop-dem-glo-90>
<CollectionClient id=goes-cmi>
<CollectionClient id=terraclimate>
<CollectionClient id=nasa-nex-gddp-cmip6>
<CollectionClient id=gpm-imerg-hhr>
<CollectionClient id=gnatsgo-rasters>
<CollectionClient id=3dep-lidar-hag>
<CollectionClient id=io-lulc-annual-v02>
<CollectionClient id=3dep-lidar-intensity>
<CollectionClient id=3dep-lidar-pointsourceid>
<CollectionClient id=mtbs>
<CollectionClient id=noaa-c-cap>
<CollectionClient id=3dep-lidar-copc>
<CollectionClient id=modis-64A1-061>
<CollectionClient id=alos-fnf-mosaic>
<CollectionClient id=3dep-lidar-returns>
<CollectionClient id=mobi>
<CollectionClient id=landsat-c2-l2>
<CollectionClient id=era5-pds>
<CollectionClient id=chloris-biomass>
<CollectionClient id=kaza-hydroforecast>
<CollectionClient id=planet-nicfi-analytic>
<CollectionClient id=modis-17A2H-061>
<CollectionClient id=modis-11A2-061>
<CollectionClient id=daymet-daily-pr>
<CollectionClient id=3dep-lidar-dtm-native>
<CollectionClient id=3dep-lidar-classification>
<CollectionClient id=3dep-lidar-dtm>
<CollectionClient id=gap>
<CollectionClient id=modis-17A2HGF-061>
<CollectionClient id=planet-nicfi-visual>
<CollectionClient id=gbif>
<CollectionClient id=modis-17A3HGF-061>
<CollectionClient id=modis-09A1-061>
<CollectionClient id=alos-dem>
<CollectionClient id=alos-palsar-mosaic>
<CollectionClient id=deltares-water-availability>
<CollectionClient id=modis-16A3GF-061>
<CollectionClient id=modis-21A2-061>
<CollectionClient id=us-census>
<CollectionClient id=jrc-gsw>
<CollectionClient id=deltares-floods>
<CollectionClient id=modis-43A4-061>
<CollectionClient id=modis-09Q1-061>
<CollectionClient id=modis-14A1-061>
<CollectionClient id=hrea>
<CollectionClient id=modis-13Q1-061>
<CollectionClient id=modis-14A2-061>
<CollectionClient id=sentinel-2-l2a>
<CollectionClient id=modis-15A2H-061>
<CollectionClient id=modis-11A1-061>
<CollectionClient id=modis-15A3H-061>
<CollectionClient id=modis-13A1-061>
<CollectionClient id=daymet-daily-na>
<CollectionClient id=nrcan-landcover>
<CollectionClient id=modis-10A2-061>
<CollectionClient id=ecmwf-forecast>
<CollectionClient id=noaa-mrms-qpe-24h-pass2>
<CollectionClient id=sentinel-1-grd>
<CollectionClient id=nasadem>
<CollectionClient id=io-lulc>
<CollectionClient id=landsat-c2-l1>
<CollectionClient id=drcog-lulc>
<CollectionClient id=chesapeake-lc-7>
<CollectionClient id=chesapeake-lc-13>
<CollectionClient id=chesapeake-lu>
<CollectionClient id=noaa-mrms-qpe-1h-pass1>
<CollectionClient id=noaa-mrms-qpe-1h-pass2>
<CollectionClient id=noaa-nclimgrid-monthly>
<CollectionClient id=goes-glm>
<CollectionClient id=usda-cdl>
<CollectionClient id=eclipse>
<CollectionClient id=esa-cci-lc>
<CollectionClient id=esa-cci-lc-netcdf>
<CollectionClient id=fws-nwi>
<CollectionClient id=usgs-lcmap-conus-v13>
<CollectionClient id=usgs-lcmap-hawaii-v10>
<CollectionClient id=noaa-climate-normals-tabular>
<CollectionClient id=noaa-climate-normals-netcdf>
<CollectionClient id=noaa-climate-normals-gridded>
<CollectionClient id=aster-l1t>
<CollectionClient id=cil-gdpcir-cc-by-sa>
<CollectionClient id=naip>
<CollectionClient id=io-lulc-9-class>
<CollectionClient id=io-biodiversity>
<CollectionClient id=noaa-cdr-sea-surface-temperature-whoi>
<CollectionClient id=noaa-cdr-ocean-heat-content>
<CollectionClient id=cil-gdpcir-cc0>
<CollectionClient id=cil-gdpcir-cc-by>
<CollectionClient id=noaa-cdr-sea-surface-temperature-whoi-netcdf>
<CollectionClient id=noaa-cdr-sea-surface-temperature-optimum-interpolation>
<CollectionClient id=modis-10A1-061>
<CollectionClient id=sentinel-5p-l2-netcdf>
<CollectionClient id=sentinel-3-olci-wfr-l2-netcdf>
<CollectionClient id=noaa-cdr-ocean-heat-content-netcdf>
<CollectionClient id=sentinel-3-synergy-aod-l2-netcdf>
<CollectionClient id=sentinel-3-synergy-v10-l2-netcdf>
<CollectionClient id=sentinel-3-olci-lfr-l2-netcdf>
<CollectionClient id=sentinel-3-sral-lan-l2-netcdf>
<CollectionClient id=sentinel-3-slstr-lst-l2-netcdf>
<CollectionClient id=sentinel-3-slstr-wst-l2-netcdf>
<CollectionClient id=sentinel-3-sral-wat-l2-netcdf>
<CollectionClient id=ms-buildings>
<CollectionClient id=sentinel-3-slstr-frp-l2-netcdf>
<CollectionClient id=sentinel-3-synergy-syn-l2-netcdf>
<CollectionClient id=sentinel-3-synergy-vgp-l2-netcdf>
<CollectionClient id=sentinel-3-synergy-vg1-l2-netcdf>
<CollectionClient id=esa-worldcover>
[4]:
collection = cat.get_collection('aster-l1t')
collection
DEBUG:pystac_client.stac_api_io:GET https://planetarycomputer.microsoft.com/api/stac/v1/collections/aster-l1t Headers: {'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
[4]:

Items#

The main functions for getting items return iterators, where pystac-client will handle retrieval of additional pages when needed. Note that one request is made for the first ten items, then a second request for the next ten.

[5]:
items = collection.get_items()

# flush stdout so we can see the exact order that things happen
def get_ten_items(items):
    for i, item in enumerate(items):
        print(f"{i}: {item}", flush=True)
        if i == 9:
            return

print('First page', flush=True)
get_ten_items(items)

print('Second page', flush=True)
get_ten_items(items)
First page
DEBUG:pystac_client.stac_api_io:GET https://planetarycomputer.microsoft.com/api/stac/v1/collections/aster-l1t/items?collections=aster-l1t Headers: {'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
0: <Item id=AST_L1T_00312272006020322_20150518201805>
1: <Item id=AST_L1T_00312272006020313_20150518201753>
2: <Item id=AST_L1T_00312272006020304_20150518201753>
3: <Item id=AST_L1T_00312272006020256_20150518201805>
4: <Item id=AST_L1T_00312272006013731_20150518201743>
5: <Item id=AST_L1T_00312272006013722_20150518201738>
6: <Item id=AST_L1T_00312272006013714_20150518201738>
7: <Item id=AST_L1T_00312272006013705_20150517144401>
8: <Item id=AST_L1T_00312272006013656_20150517144401>
9: <Item id=AST_L1T_00312272006013647_20150517144406>
Second page
DEBUG:pystac_client.stac_api_io:GET https://planetarycomputer.microsoft.com/api/stac/v1/collections/aster-l1t/items?collections=aster-l1t&token=next:aster-l1t:AST_L1T_00312272006013647_20150517144406 Headers: {'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
0: <Item id=AST_L1T_00312272006013638_20150517144356>
1: <Item id=AST_L1T_00312272006013629_20150517144344>
2: <Item id=AST_L1T_00312272006013620_20150517144344>
3: <Item id=AST_L1T_00312272006013612_20150517144400>
4: <Item id=AST_L1T_00312272006013603_20150517144346>
5: <Item id=AST_L1T_00312272006013554_20150517144346>
6: <Item id=AST_L1T_00312272006013545_20150517144346>
7: <Item id=AST_L1T_00312272006013536_20150517144340>
8: <Item id=AST_L1T_00312272006013527_20150517144346>
9: <Item id=AST_L1T_00312272006013519_20150517144336>