Skip to main content
The STAC data source allows you to read data from a SpatioTemporal Asset Catalog (STAC) API. The data source supports reading STAC items and collections.

Usage

To use the STAC data source, you can load a STAC catalog into a Sedona DataFrame using the stac format. The path can be either a local STAC collection JSON file or an HTTP/HTTPS endpoint to retrieve the collection JSON file. You can load a STAC collection from a local collection file:
You can load a STAC collection from a s3 collection file object:
You can also load a STAC collection from an HTTP/HTTPS endpoint:
output:

Filter Pushdown

The STAC data source supports predicate pushdown for spatial and temporal filters. The data source can push down spatial and temporal filters to the underlying data source to reduce the amount of data that needs to be read.

Spatial Filter Pushdown

Spatial filter pushdown allows the data source to apply spatial predicates (e.g., st_contains, st_intersects) directly at the data source level, reducing the amount of data transferred and processed.

Temporal Filter Pushdown

Temporal filter pushdown allows the data source to apply temporal predicates (e.g., BETWEEN, >=, <=) directly at the data source level, similarly reducing the amount of data transferred and processed.

Examples

Here are some examples demonstrating how to query a STAC data source that is loaded into a table named STAC_TABLE.

SQL Select Without Filters

SQL Select With Temporal Filter

In this example, the data source will push down the temporal filter to the underlying data source.

SQL Select With Spatial Filter

In this example, the data source will push down the spatial filter to the underlying data source.

Sedona Configuration for STAC Reader

When using the STAC reader in Sedona, several configuration options can be set to control the behavior of the reader. These configurations are typically set in a Map[String, String] and passed to the reader. Below are the key sedona configuration options:
default:"-1"
This option specifies the maximum number of item files that can be included in a single partition. It helps in controlling the size of partitions. The default value is set to -1, meaning the system will automatically determine the number of item files per partition.
default:"-1"
This option sets the number of partitions to be created for the STAC data. It allows for better control over data distribution and parallel processing. The default value is set to -1, meaning the system will automatically determine the number of item files per partition.
Below are reader options that can be set to control the behavior of the STAC reader:
default:"-1"
This option specifies the maximum number of items to be loaded from the STAC collection. It helps in limiting the amount of data processed. The default value is set to -1, meaning all items will be loaded.
A SQL LIMIT clause bounds the scan only when it applies directly to the scan, with no other predicates in between. When LIMIT is combined with filters — for example WHERE datetime > '2023-01-01' ... LIMIT 1000 — the limit cannot be pushed into the reader safely, so the reader still enumerates every item matching the filters before the limit is applied. For interactive or exploratory reads against large collections or search endpoints, set itemsLimitMax to bound how many items the reader fetches.
default:"1000000"
This option specifies the threshold for reporting the progress of item loading. It helps in monitoring the progress of the loading process. The default value is set to 1000000, meaning the progress will be reported every 1,000,000 items loaded.
default:"10"
This option specifies the maximum number of items to be requested in a single API call. It helps in controlling the size of each request. The default value is set to 10.
default:"false"
This option controls automatic Item deduplication for parallel temporal reads. The default is false: a remote scan with a finite effective temporal range is split into per-interval requests that executors paginate concurrently, and when the range needs more than one slice, Spark performs a distributed deduplication by (collection, id); a single slice needs no identity shuffle. Set the option to true to skip automatic deduplication and expose the raw slice rows. Under a conforming STAC API whose contents remain stable during the scan, those rows have at-least-once semantics: an interval-valued Item can intersect several requests and therefore appear more than once in this mode. The effective range may come from the Collection extent, an endpoint datetime constraint, a pushed temporal filter, or their intersection.A positive itemsLimitMax or a directly pushed global SQL LIMIT always retains sequential pagination, in either deduplication mode: a cap requires the ordered counting walk to know when to stop, and under the default mode a raw limit applied below deduplication could additionally return too few unique Items. See the itemsLimitMax option above for how LIMIT interacts with other predicates.
Automatic deduplication requires stable Item identity and stable source contents during the scan. Item IDs are scoped to a Collection, so multi-Collection search results must provide collection; for Items reached from a specific Collection endpoint, the reader fills a missing value from that parent Collection. If two slice requests return different versions of the same (collection, id), Spark may retain either version. The default shuffle can still outperform serially walking every STAC result page on the driver, but the tradeoff becomes less favorable for small scans, wide rows, or Items spanning many slices. Set allowDuplicates=true only when duplicate rows are acceptable or the query deliberately handles them before counts, aggregates, joins, limits, or writes.
default:"month"
This option selects month (the default) or day calendar slices for eligible parallel scans in either deduplication mode. Daily slices can improve load balancing for a short, dense range, but create one executor-paginated request chain per day and can return a long-lived Item through more slices. Prefer monthly slices for broad ranges to avoid excessive partitions, duplicate amplification, and API requests. Planning memory and request fan-out grow with the number of slices, not the number of result pages.
This option specifies HTTP headers to include in STAC API requests. It should be a JSON-encoded string containing a dictionary of header key-value pairs. This is useful for authentication and custom headers. Example: {"Authorization": "Basic <base64_credentials>"}
default:"true"
This option controls whether output database raster fields are generated for each row. When enabled, the “assets” field in each row is processed so that each asset is updated with a raster linked to its “href” value. The default value is true.The generated rasters read pixels the same way as RS_FromPath: the GeoTIFF’s per-band scale and offset are applied by default, so band values arrive in physical units (for example, Sentinel-2 Collection 1 surface reflectance between 0 and 1) rather than raw digital numbers. Pass .option("raster.reader.auto-rescale", "false") to keep the raw digital numbers. See Band values, scale, and offset.
These configurations can be combined into a single Map[String, String] and passed to the STAC reader as shown below:
These options above provide fine-grained control over how the STAC data is read and processed in Sedona.

Python API

The Python API allows you to interact with a SpatioTemporal Asset Catalog (STAC) API using the Client class. This class provides methods to open a connection to a STAC API, retrieve collections, and search for items with various filters.

Client Class

Methods

open(url: str, headers: Optional[dict] = None) -> Client Opens a connection to the specified STAC API URL. Parameters:
str
required
The URL of the STAC API to connect to. Example: "https://planetarycomputer.microsoft.com/api/stac/v1"
[dict]
Optional dictionary of HTTP headers for authentication or custom headers. Example: {"Authorization": "Bearer token123"}
Returns:
Client
An instance of the Client class connected to the specified URL.
with_basic_auth(username: str, password: str) -> Client Adds HTTP Basic Authentication to the client. This method encodes the username and password using Base64 and adds the appropriate Authorization header for HTTP Basic Authentication. Parameters:
str
required
The username for authentication. For API keys, this is typically the API key itself. Example: "your_api_key"
str
required
The password for authentication. For API keys, this is often left empty. Example: ""
Returns:
Client
Returns self for method chaining.
with_bearer_token(token: str) -> Client Adds Bearer Token Authentication to the client. This method adds the appropriate Authorization header for Bearer Token authentication, commonly used with OAuth2 and API tokens. Parameters:
str
required
The bearer token for authentication. Example: "your_access_token_here"
Returns:
Client
Returns self for method chaining.
get_collection(collection_id: str) -> CollectionClient Retrieves a collection client for the specified collection ID. Parameters:
str
required
The ID of the collection to retrieve. Example: "aster-l1t"
Returns:
CollectionClient
An instance of the CollectionClient class for the specified collection.
search(*ids: Union[str, list], collection_id: str, bbox: Optional[list] = None, geometry: Optional[Union[str, BaseGeometry, list]] = None, datetime: Optional[Union[str, datetime.datetime, list]] = None, max_items: Optional[int] = None, return_dataframe: bool = True) -> Union[Iterator[PyStacItem], DataFrame] Searches for items in the specified collection with optional filters. Parameters:
Union[str, list]
A positional variable argument parameter of item IDs to filter the items. Example: "item_id1" or ["item_id1", "item_id2"]
str
required
The ID of the collection to search in. Example: "aster-l1t"
Optional[list]
A list of bounding boxes for filtering the items. Each bounding box is represented as a list of four float values: [min_lon, min_lat, max_lon, max_lat]. Example: [[ -180.0, -90.0, 180.0, 90.0 ]]
Optional[Union[str, datetime.datetime, list]]
A single datetime, RFC 3339-compliant timestamp, or a list of date-time ranges for filtering the items. Example:
  • "2020-01-01T00:00:00Z"
  • datetime.datetime(2020, 1, 1)
  • [["2020-01-01T00:00:00Z", "2021-01-01T00:00:00Z"]]
Optional[Union[str, BaseGeometry, list]]
Shapely geometry object(s) or WKT string(s) for spatial filtering. Can be a single geometry, a WKT string, or a list of geometries/WKT strings. If both bbox and geometry are provided, geometry takes precedence. Geometry filtering is evaluated by Spark, not by the STAC API. Example: "POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))"
Optional[int]
The maximum number of STAC API results to return. Supported single-collection bbox/datetime searches follow pystac-client semantics and trust the API’s matching behavior. Multiple bboxes are queried independently, unioned, and deduplicated before the final result limit; extended Spark-side filters are applied before that limit. Example: 100
bool
default:"True"
If True (default), return the result as a Spark DataFrame instead of an iterator of PyStacItem objects. Example: True
Returns:
Union[Iterator[PyStacItem], DataFrame]
An iterator of PyStacItem objects or a Spark DataFrame that matches the specified filters.

Sample Code

Initialize the Client

Search Items on a Collection Within a Year

Search Items on a Collection Within a Day and Max Items

max_items follows pystac-client semantics: it limits the total number of Items returned, while itemsLimitPerRequest is only the requested page size. search() does not expose itemsLimitPerRequest — the client chooses the page size itself, and that option’s default of 10 applies when loading through the DataFrame reader. With a named collection, at most one datetime interval, optional bbox values, and no ID or geometry filter, the client sends each bbox to the Collection’s advertised Items endpoint as an independent search. A positive max_items also caps each search, paging at min(200, max_items). A caller that supplies no max_items — as save_to_geoparquet does — still has its bbox and datetime pushed to the API, so the endpoint rather than Spark rejects non-matching Items; each bbox’s search runs as its own executor-paginated request chain with 200-Item pages and no enumeration ceiling. It unions multiple bbox results, removes duplicate (collection, id) pairs, and then applies the global max_items limit. This union deduplication happens in the client and is independent of the allowDuplicates reader option, which governs automatic deduplication for parallel temporal-slice reads only. Multiple datetime intervals, ID filters, and the geometry parameter are extensions evaluated by Spark; those shapes remain uncapped at the reader so Spark can evaluate every Item, but use request pages of 200 Items to reduce pagination overhead.

Search Items with Bounding Box and Interval

Search Multiple Items with Multiple Bounding Boxes

Search Items and Get DataFrame as Return with Multiple Intervals

Save Items in DataFrame to GeoParquet with Both Bounding Boxes and Intervals

These examples demonstrate how to use the Client class to search for items in a STAC collection with various filters and return the results as either an iterator of PyStacItem objects or a Spark DataFrame.

Authentication

Many STAC services require authentication to access their data. The STAC client supports multiple authentication methods including HTTP Basic Authentication, Bearer Token Authentication, and custom headers.

Basic Authentication

Basic authentication is commonly used with API keys or username/password combinations. Many services (like Planet Labs) use API keys as the username with an empty password.

Bearer Token Authentication

Bearer token authentication is used with OAuth2 tokens and JWT tokens. Note that some services may only support specific authentication methods.

Custom Headers

You can also pass custom headers directly when creating the client, which is useful for services with non-standard authentication requirements.

Authentication with Scala DataSource

When using the STAC data source directly in Scala or through Spark SQL, you can pass authentication headers as a JSON-encoded option:

Important Notes

  • Authentication methods are mutually exclusive: Setting a new authentication method will overwrite any previously set Authorization header, but other custom headers remain unchanged.
  • Headers are propagated: Headers set on the Client are automatically passed to all collection and item requests.
  • Service-specific requirements: Different STAC services may require different authentication methods. For example, Planet Labs requires Basic Authentication rather than Bearer tokens for collection access.
  • Backward compatibility: All authentication parameters are optional. Existing code that accesses public STAC services without authentication will continue to work unchanged.

References