Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

## [0.5.6-beta.1] - 2025-02-25
## [0.5.6] - 2025-02-26

### Added

Expand Down Expand Up @@ -149,8 +149,8 @@ Non-functional release to fix releasing from Github actions.

Initial release.

[Unreleased]: https://github.com/gadomski/stacrs/compare/v0.5.6-beta.1...main
[0.5.6-beta.1]: https://github.com/gadomski/stacrs/compare/v0.5.5...v0.5.6-beta.1
[Unreleased]: https://github.com/gadomski/stacrs/compare/v0.5.6...main
[0.5.6]: https://github.com/gadomski/stacrs/compare/v0.5.5...v0.5.6
[0.5.5]: https://github.com/gadomski/stacrs/compare/v0.5.4...v0.5.5
[0.5.4]: https://github.com/gadomski/stacrs/compare/v0.5.3...v0.5.4
[0.5.3]: https://github.com/gadomski/stacrs/compare/v0.5.2...v0.5.3
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Contributing to **stacrs**
# Contributing

First off, thanks for contributing!
We appreciates you.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stacrs"
version = "0.5.6-beta.1"
version = "0.5.6"
edition = "2021"
publish = false

Expand Down
30 changes: 14 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@
![PyPI - License](https://img.shields.io/pypi/l/stacrs?style=for-the-badge)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg?style=for-the-badge)](./CODE_OF_CONDUCT)

A small no-dependency Python package for [STAC](https://stacspec.org/), using Rust under the hood.
A Python package for [STAC](https://stacspec.org/) using Rust under the hood.

## Why?

Q: We already have [PySTAC](https://github.com/stac-utils/pystac), so why did we make a new STAC Python library?
Q: We already have [PySTAC](https://github.com/stac-utils/pystac), so why **stacrs**?

A: We want to provide a couple of things in [stac-rs](https://github.com/stac-utils/stac-rs) (a collection of STAC Rust libraries) to the Python ecosystem:
A: **stacrs** can

- Read, write, and search [stac-geoparquet](https://github.com/stac-utils/stac-geoparquet)
- `async` functions
- Go to and from [arrow](https://arrow.apache.org/) tables, allowing easy interoperability with (e.g.) [GeoPandas](https://geopandas.org/en/stable/)
- `async`

If you don't need those things, **stacrs** probably isn't for you — use **pystac** and its friend, [pystac-client](https://github.com/stac-utils/pystac-client), instead.
If you don't need those things, **stacrs** probably isn't for you — use **pystac** and its friend, [pystac-client](https://github.com/stac-utils/pystac-client).

## Usage

Expand All @@ -28,7 +29,7 @@ Install via **pip**:
# basic
python -m pip install stacrs

# add methods to return arrow tables
# support arrow tables
python -m pip install 'stacrs[arrow]'
```

Expand Down Expand Up @@ -56,6 +57,7 @@ items = await stacrs.search(
from geopandas import GeoDataFrame
table = await stacrs.search_to_arrow(...)
data_frame = GeoDataFrame.from_arrow(table)
items = stacrs.from_arrow(data_frame.to_arrow())

# Write items to a stac-geoparquet file
await stacrs.write("items.parquet", items)
Expand Down Expand Up @@ -117,17 +119,9 @@ Options:
> [!NOTE]
> Before **stacrs** v0.5.4, the CLI was its own PyPI package named **stacrs-cli**, which is no longer needed.

## Comparisons
## stac-geoparquet

This package (intentionally) has limited functionality, as it is _not_ intended to be a replacement for existing Python STAC packages.
[pystac](https://pystac.readthedocs.io) is a mature Python library with a significantly richer API for working with STAC objects.
For querying STAC APIs, [pystac-client](https://pystac-client.readthedocs.io) is more feature-rich than our simplistic `stacrs.search`.

That being said, it is hoped that **stacrs** will be a nice complement to the existing Python STAC ecosystem by providing a no-dependency package with unique capabilities, such as searching directly into a stac-geoparquet file.

### stac-geoparquet

**stacrs** also replicates much of the behavior in the [stac-geoparquet](https://github.com/stac-utils/stac-geoparquet) library, and even uses some of the same Rust dependencies.
**stacrs** replicates much of the behavior in the [stac-geoparquet](https://github.com/stac-utils/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
Expand All @@ -149,6 +143,10 @@ scripts/test

See [CONTRIBUTING.md](./CONTRIBUTING.md) for more information about contributing to this project.

> [!TIP]
> We ship our wheels with **libduckdb** so users don't have to worry about having it installed.
> You only need it if you're doing development.

### DuckDB

By default, this package expects **libduckdb** to be present on your system.
Expand Down
14 changes: 14 additions & 0 deletions docs/api/arrow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
description: Go to and from arrow
---

# Arrow

These functions require the `arrow` extra, e.g.:

```shell
python -m pip install 'stacrs[arrow]'
```

::: stacrs.to_arrow
::: stacrs.from_arrow
26 changes: 15 additions & 11 deletions docs/example.ipynb

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ nav:
- Example notebook: example.ipynb
- API:
- api/index.md
- arrow: api/arrow.md
- duckdb: api/duckdb.md
- migrate: api/migrate.md
- read: api/read.md
Expand Down Expand Up @@ -47,6 +48,8 @@ plugins:
show_source: false
show_symbol_type_toc: true
signature_crossrefs: true
import:
- https://kylebarron.dev/arro3/latest/objects.inv
- search
- social:
cards_layout_options:
Expand Down
33 changes: 18 additions & 15 deletions stacrs.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class DuckdbClient:
kwargs: Additional parameters to pass in to the search.

Returns:
dict[str, Any]: A feature collection of STAC items.
A feature collection of STAC items.
"""

def search_to_arrow(
Expand All @@ -86,9 +86,13 @@ class DuckdbClient:
) -> arro3.core.Table | None:
"""Search a stac-geoparquet file with duckdb, returning an arrow table
suitable for loading into (e.g.) GeoPandas.

**stacrs** must be installed with the `arrow` extra, e.g. `python -m pip
*install 'stacrs[arrow]'.

Because DuckDB has arrow as a core output format, this can be more
performant than going through a JSON dictionary.

Args:
href: The stac-geoparquet file.
ids: Array of Item ids to return.
Expand All @@ -115,7 +119,7 @@ class DuckdbClient:
kwargs: Additional parameters to pass in to the search.

Returns:
arro3.core.Table | None: An arrow table, or none if no records were returned.
An arrow table, or none if no records were returned.

Examples:
>>> table = client.search_to_arrow("data/100-sentinel-2-items.parquet")
Expand Down Expand Up @@ -180,7 +184,7 @@ def migrate(value: dict[str, Any], version: Optional[str] = None) -> dict[str, A
value will be migrated to the latest stable version.

Returns:
dict[str, Any]: The migrated dictionary
The migrated dictionary

Examples:
>>> with open("examples/simple-item.json") as f:
Expand All @@ -206,7 +210,7 @@ async def read(
object store, e.g. your AWS credentials.

Returns:
dict[str, Any]: The STAC value
The STAC value

Examples:
>>> item = await stacrs.read("item.json")
Expand All @@ -216,30 +220,30 @@ def from_arrow(
table: arro3.core.Table,
) -> dict[str, Any]:
"""
Converts an [arro3.core.table][] to a STAC item collection.
Converts an [arro3.core.Table][] to a STAC item collection.

Requires **stacrs** to be installed with the `arrow` extra.

Args:
table: The table

Returns:
dict[str, Any]: The STAC item collection
The STAC item collection
"""

def to_arrow(
items: list[dict[str, Any]] | dict[str, Any],
) -> arro3.core.Table:
"""
Converts items to an [arro3.core.table][].
Converts items to an [arro3.core.Table][].

Requires **stacrs** to be installed with the `arrow` extra.

Args:
items: Either an iterable of items or a item collection
items: Either a list of items or a item collection

Returns:
arro3.core.Table: The table
The table
"""

async def search(
Expand Down Expand Up @@ -298,7 +302,7 @@ async def search(
kwargs: Additional parameters to pass in to the search.

Returns:
list[dict[str, Any]]: A list of the returned STAC items.
A list of the returned STAC items.

Examples:
>>> items = await stacrs.search(
Expand Down Expand Up @@ -372,7 +376,7 @@ async def search_to(
to None.

Returns:
int: The number of items written
The number of items written

Examples:
>>> count = await stacrs.search_to("out.parquet",
Expand Down Expand Up @@ -404,9 +408,8 @@ async def write(
object store, e.g. your AWS credentials.

Returns:
dict[str, str] | None: The result of putting data into an object store,
e.g. the e_tag and the version. None is returned if the file was written
locally.
The result of putting data into an object store, e.g. the e_tag and the
version. None is returned if the file was written locally.

Examples:
>>> with open("items.json") as f:
Expand All @@ -423,7 +426,7 @@ def version(name: str | None = None) -> str | None:
values are "stac", "stac-api", "stac-duckdb", or "duckdb".

Returns:
str: The version, or None if the name is not recognized as an upstream.
The version, or None if the name is not recognized as an upstream.

Examples:
>>> stacrs.version()
Expand Down