Skip to content

A Python package for STAC using Rust under the hood

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

stac-utils/stacrs

stacrs

GitHub Workflow Status GitHub Workflow Status PyPI - Version Conda Downloads PyPI - License Contributor Covenant

A Python package for STAC using Rust under the hood.

Why?

Q: We already have PySTAC, so why stacrs?

A: stacrs can

If you don't need those things, stacrs probably isn't for you — use pystac and its friend, pystac-client.

Usage

Install via pip:

# basic
python -m pip install stacrs

# support arrow tables
python -m pip install 'stacrs[arrow]'

Or via conda:

conda install conda-forge::stacrs

Then:

import asyncio
import stacrs

async def main() -> None:
    # Search a STAC API
    items = await stacrs.search(
        "https://landsatlook.usgs.gov/stac-server",
        collections="landsat-c2l2-sr",
        intersects={"type": "Point", "coordinates": [-105.119, 40.173]},
        sortby="-properties.datetime",
        max_items=100,
    )

    # If you installed with `pystac[arrow]`:
    from geopandas import GeoDataFrame

    table = stacrs.to_arrow(items)
    data_frame = GeoDataFrame.from_arrow(table)
    items = stacrs.from_arrow(data_frame.to_arrow())

    # Write items to a stac-geoparquet file
    await stacrs.write("/tmp/items.parquet", items)

    # Read items from a stac-geoparquet file as an item collection
    item_collection = await stacrs.read("/tmp/items.parquet")

    # Use `search_to` for better performance if you know you'll be writing the items
    # to a file
    await stacrs.search_to(
        "/tmp/items.parquet",
        "https://landsatlook.usgs.gov/stac-server",
        collections="landsat-c2l2-sr",
        intersects={"type": "Point", "coordinates": [-105.119, 40.173]},
        sortby="-properties.datetime",
        max_items=100,
    )

asyncio.run(main())

See the documentation for details. In particular, our examples demonstrate some of the more interesting features.

CLI

stacrs comes with a CLI:

stacrs -h

Note

Before stacrs v0.5.4, the CLI was its own PyPI package named stacrs-cli, which is no longer needed.

stac-geoparquet

stacrs replicates much of the behavior in the stac-geoparquet library, and even uses some of the same Rust dependencies. We believe there are a couple of issues with stac-geoparquet that make stacrs a worthy replacement:

  • The stac-geoparquet repo includes Python dependencies
  • It doesn't have a nice one-shot API for reading and writing
  • It includes some leftover code and logic from its genesis as a tool for the Microsoft Planetary Computer

We test to ensure compatibility between the two libraries, and we intend to consolidate to a single "stac-geoparquet" library at some point in the future.

Development

Get Rust, uv, and (optionally) libduckdb. Then:

git clone [email protected]:stac-utils/stacrs.git
cd stacrs
scripts/test

See CONTRIBUTING.md for more information about contributing to this project.

DuckDB

By default, this package expects libduckdb to be present on your system. If you get this sort of error when building:

  = note: ld: library 'duckdb' not found

Set your DUCKDB_LIB_DIR to point to your libduckdb. If you're using homebrew, that might look like this:

export DUCKDB_LIB_DIR=/opt/homebrew/lib

Alternatively, you can use the duckdb-bundled feature to build DuckDB bindings into the Rust library:

maturin dev --uv -F duckdb-bundled && pytest

Warning

Building DuckDB bundled takes a long while.

License

stacrs is dual-licensed under both the MIT license and the Apache license (Version 2.0). See LICENSE-APACHE and LICENSE-MIT for details.