diff --git a/CHANGELOG.md b/CHANGELOG.md index 6963703..eb83ce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Source distribution to PyPI publish ([#92](https://github.com/stac-utils/rustac-py/pull/92)) - `rustac.sha` ([#99](https://github.com/stac-utils/rustac-py/pull/99)) +- Typed dictionaries for STAC entities ([#101](https://github.com/stac-utils/rustac-py/pull/101)) ### Fixed - Deterministic asset ordering ([rustac #709](https://github.com/stac-utils/rustac/pull/709), [#93](https://github.com/stac-utils/rustac-py/pull/93)) +- Normalize search output ([#102](https://github.com/stac-utils/rustac-py/pull/102)) ## [0.6.0] - 2025-04-18 diff --git a/python/rustac/rustac.pyi b/python/rustac/rustac.pyi index 1134685..b1d5df4 100644 --- a/python/rustac/rustac.pyi +++ b/python/rustac/rustac.pyi @@ -56,8 +56,8 @@ class DuckdbClient: filter: Optional[str | dict[str, Any]] = None, query: Optional[dict[str, Any]] = None, **kwargs: str, - ) -> dict[str, Any]: - """Search a stac-geoparquet file with duckdb, returning an item collection. + ) -> list[dict[str, Any]]: + """Search a stac-geoparquet file with duckdb, returning a list of items. Args: href: The stac-geoparquet file. @@ -85,7 +85,7 @@ class DuckdbClient: kwargs: Additional parameters to pass in to the search. Returns: - A feature collection of STAC items. + A list of STAC items. """ def search_to_arrow( @@ -264,7 +264,7 @@ async def search( query: Optional[dict[str, Any]] = None, use_duckdb: Optional[bool] = None, **kwargs: str, -) -> dict[str, Any]: +) -> list[dict[str, Any]]: """ Searches a STAC API server. @@ -303,10 +303,10 @@ async def search( kwargs: Additional parameters to pass in to the search. Returns: - A feature collection of the returned STAC items. + STAC items Examples: - >>> item_collection = await rustac.search( + >>> items = await rustac.search( ... "https://landsatlook.usgs.gov/stac-server", ... collections=["landsat-c2l2-sr"], ... intersects={"type": "Point", "coordinates": [-105.119, 40.173]}, diff --git a/src/duckdb.rs b/src/duckdb.rs index b0b3b5a..558af51 100644 --- a/src/duckdb.rs +++ b/src/duckdb.rs @@ -59,7 +59,7 @@ impl DuckdbClient { filter: Option, query: Option>, kwargs: Option>, - ) -> Result> { + ) -> Result> { let search = crate::search::build( intersects, ids, @@ -81,9 +81,9 @@ impl DuckdbClient { .map_err(|err| PyException::new_err(err.to_string()))?; client.search(&href, search)? }; - let dict = pythonize::pythonize(py, &item_collection)?; - let dict = dict.extract()?; - Ok(dict) + let list = pythonize::pythonize(py, &item_collection.items)?; + let list = list.extract()?; + Ok(list) } #[pyo3(signature = (href, *, intersects=None, ids=None, collections=None, limit=None, bbox=None, datetime=None, include=None, exclude=None, sortby=None, filter=None, query=None, **kwargs))] diff --git a/tests/test_duckdb.py b/tests/test_duckdb.py index 29aed6e..aec217e 100644 --- a/tests/test_duckdb.py +++ b/tests/test_duckdb.py @@ -10,26 +10,16 @@ def client() -> DuckdbClient: def test_search(client: DuckdbClient) -> None: - item_collection = client.search("data/extended-item.parquet") - assert len(item_collection["features"]) == 1 + items = client.search("data/extended-item.parquet") + assert len(items) == 1 def test_search_offset(client: DuckdbClient) -> None: - item_collection = client.search( - "data/100-sentinel-2-items.parquet", offset=0, limit=1 - ) - assert ( - item_collection["features"][0]["id"] - == "S2B_MSIL2A_20241203T174629_R098_T13TDE_20241203T211406" - ) - - item_collection = client.search( - "data/100-sentinel-2-items.parquet", offset=1, limit=1 - ) - assert ( - item_collection["features"][0]["id"] - == "S2A_MSIL2A_20241201T175721_R141_T13TDE_20241201T213150" - ) + items = client.search("data/100-sentinel-2-items.parquet", offset=0, limit=1) + assert items[0]["id"] == "S2B_MSIL2A_20241203T174629_R098_T13TDE_20241203T211406" + + items = client.search("data/100-sentinel-2-items.parquet", offset=1, limit=1) + assert items[0]["id"] == "S2A_MSIL2A_20241201T175721_R141_T13TDE_20241201T213150" def test_get_collections(client: DuckdbClient) -> None: @@ -37,6 +27,7 @@ def test_get_collections(client: DuckdbClient) -> None: assert len(collections) == 1 +@pytest.mark.skip("slow") def test_init_with_config() -> None: DuckdbClient(use_s3_credential_chain=True, use_hive_partitioning=True)