{"id":27611587,"url":"https://github.com/stac-utils/rustac-py","last_synced_at":"2026-03-01T00:02:49.797Z","repository":{"id":264020071,"uuid":"892067211","full_name":"stac-utils/rustac-py","owner":"stac-utils","description":"The power of Rust for the Python STAC ecosystem","archived":false,"fork":false,"pushed_at":"2026-02-12T18:38:11.000Z","size":18233,"stargazers_count":44,"open_issues_count":7,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-13T01:04:59.863Z","etag":null,"topics":["python","stac"],"latest_commit_sha":null,"homepage":"https://stac-utils.github.io/rustac-py/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stac-utils.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":"CODE_OF_CONDUCT","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-21T13:02:22.000Z","updated_at":"2026-02-12T18:29:36.000Z","dependencies_parsed_at":"2025-01-02T17:38:51.866Z","dependency_job_id":"2fc8da4c-2b43-44e5-af57-a12661351d5c","html_url":"https://github.com/stac-utils/rustac-py","commit_stats":null,"previous_names":["gadomski/stacrs","stac-utils/stacrs","stac-utils/rustac-py"],"tags_count":44,"template":false,"template_full_name":null,"purl":"pkg:github/stac-utils/rustac-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Frustac-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Frustac-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Frustac-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Frustac-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stac-utils","download_url":"https://codeload.github.com/stac-utils/rustac-py/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Frustac-py/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29955885,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T22:53:01.873Z","status":"ssl_error","status_checked_at":"2026-02-28T22:52:50.699Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","stac"],"created_at":"2025-04-23T00:21:50.341Z","updated_at":"2026-03-01T00:02:49.728Z","avatar_url":"https://github.com/stac-utils.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rustac\n\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/stac-utils/rustac-py/ci.yaml?branch=main\u0026style=for-the-badge)](https://github.com/stac-utils/rustac-py/actions/workflows/ci.yaml)\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/stac-utils/rustac-py/docs.yaml?branch=main\u0026style=for-the-badge\u0026label=Docs)](https://stac-utils.github.io/rustac-py/latest/)\n[![PyPI - Version](https://img.shields.io/pypi/v/rustac?style=for-the-badge)](https://pypi.org/project/rustac)\n[![Conda forge](https://img.shields.io/conda/v/conda-forge/rustac?style=for-the-badge)](https://anaconda.org/conda-forge/rustac)\n![PyPI - License](https://img.shields.io/pypi/l/rustac?style=for-the-badge)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg?style=for-the-badge)](./CODE_OF_CONDUCT)\n\n![The rustac logo](https://stac-utils.github.io/rustac-py/latest/img/rustac-small.png)\n\nThe power of Rust for the Python [STAC](https://stacspec.org/) ecosystem.\n\n\u003c!-- markdownlint-disable MD028 --\u003e\n\u003e [!TIP]\n\u003e We pronounce **rustac** \"ruh-stac\".\n\n\u003e [!NOTE]\n\u003e Until 2025-04-17, this package was named **stacrs**.\n\u003e See [this RFC](https://github.com/stac-utils/rustac/issues/641) for context on the name change.\n\u003c!-- markdownlint-enable MD028 --\u003e\n\n## Why?\n\nQ: We already have [PySTAC](https://github.com/stac-utils/pystac), so why **rustac**?\n\nA: **rustac** can\n\n- Read, write, and search [stac-geoparquet](https://github.com/stac-utils/stac-geoparquet)\n- Go to and from [arrow](https://arrow.apache.org/) tables, allowing easy interoperability with (e.g.) [GeoPandas](https://geopandas.org/en/stable/)\n- `async`\n\nIf you don't need those things, **rustac** probably isn't for you — use **pystac** and its friend, [pystac-client](https://github.com/stac-utils/pystac-client).\n\n## Installation\n\n**rustac** has zero required dependencies.\nInstall via **pip**:\n\n```shell\n# basic\npython -m pip install rustac\n\n# support arrow tables\npython -m pip install 'rustac[arrow]'\n```\n\nOr via **conda**:\n\n```shell\nconda install conda-forge::rustac\n```\n\n### From source\n\nYou'll need [Rust](https://rustup.rs/).\nBy default, **rustac** wants to find DuckDB on your system:\n\n```shell\nbrew install duckdb  # if you're using Homebrew ... if not, get DuckDB another way\npython -m pip install -U git+https://github.com/stac-utils/rustac-py\n```\n\nIf you don't want to (or can't) install DuckDB,  _can_ build DuckDB as a \"bundled\" build (warning: it takes a while):\n\n```shell\nMATURIN_PEP517_ARGS=\"--features=duckdb-bundled\" python -m pip install -U git+https://github.com/stac-utils/rustac-py\n```\n\n## Usage\n\n```python\nimport asyncio\nimport rustac\n\nasync def main() -\u003e None:\n    # Search a STAC API\n    items = await rustac.search(\n        \"https://landsatlook.usgs.gov/stac-server\",\n        collections=\"landsat-c2l2-sr\",\n        intersects={\"type\": \"Point\", \"coordinates\": [-105.119, 40.173]},\n        sortby=\"-properties.datetime\",\n        max_items=100,\n    )\n\n    # If you installed with `pystac[arrow]`:\n    from geopandas import GeoDataFrame\n\n    table = rustac.to_arrow(items)\n    data_frame = GeoDataFrame.from_arrow(table)\n    items = rustac.from_arrow(data_frame.to_arrow())\n\n    # Write items to a stac-geoparquet file\n    await rustac.write(\"/tmp/items.parquet\", items)\n\n    # Read items from a stac-geoparquet file as an item collection\n    item_collection = await rustac.read(\"/tmp/items.parquet\")\n\n    # Use `search_to` for better performance if you know you'll be writing the items\n    # to a file\n    await rustac.search_to(\n        \"/tmp/items.parquet\",\n        \"https://landsatlook.usgs.gov/stac-server\",\n        collections=\"landsat-c2l2-sr\",\n        intersects={\"type\": \"Point\", \"coordinates\": [-105.119, 40.173]},\n        sortby=\"-properties.datetime\",\n        max_items=100,\n    )\n\nasyncio.run(main())\n```\n\nSee [the documentation](https://stac-utils.github.io/rustac-py) for details.\nIn particular, our [examples](https://stac-utils.github.io/rustac-py/latest/generated/gallery/) demonstrate some of the more interesting features.\n\n## Command line interface (CLI)\n\n**rustac** comes with a CLI:\n\n```bash\nrustac -h\n```\n\n## stac-geoparquet\n\n**rustac** 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.\nWe believe there are a couple of issues with **stac-geoparquet** that make **rustac** a worthy replacement:\n\n- The **stac-geoparquet** repo includes Python dependencies\n- It doesn't have a nice one-shot API for reading and writing\n- It includes some leftover code and logic from its genesis as a tool for the [Microsoft Planetary Computer](https://planetarycomputer.microsoft.com/)\n\nWe test to ensure [compatibility](https://github.com/stac-utils/rustac/blob/main/scripts/validate-stac-geoparquet) between the two libraries, and we intend to consolidate to a single \"stac-geoparquet\" library at some point in the future.\n\n## Development\n\nGet [Rust](https://rustup.rs/), [uv](https://docs.astral.sh/uv/getting-started/installation/), and (optionally) [libduckdb](https://duckdb.org/docs/installation/index).\nThen:\n\n```shell\ngit clone git@github.com:stac-utils/rustac-py.git\ncd rustac-py\nscripts/test\n```\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for more information about contributing to this project.\n\n### DuckDB\n\nBy default, this package expects **libduckdb** to be present on your system.\nIf you get this sort of error when building:\n\n```shell\n  = note: ld: library 'duckdb' not found\n```\n\nSet your `DUCKDB_LIB_DIR` to point to your **libduckdb**.\nIf you're using [homebrew](https://brew.sh/), that might look like this:\n\n```shell\nexport DUCKDB_LIB_DIR=/opt/homebrew/lib\n```\n\nAlternatively, you can use the `duckdb-bundled` feature to build DuckDB bindings into the Rust library:\n\n```shell\nmaturin dev --uv -F duckdb-bundled \u0026\u0026 pytest\n```\n\n\u003e [!WARNING]\n\u003e Building DuckDB [bundled](https://github.com/duckdb/duckdb-rs?tab=readme-ov-file#notes-on-building-duckdb-and-libduckdb-sys) takes a long while.\n\n### Docs\n\nIf you want to run an off-cycle docs update (e.g. if you fixed something and want to post it without having to make a new release):\n\n```shell\nmike deploy [version] latest --push\n```\n\n## Acknowledgements\n\nWe'd like to thank [@jkeifer](https://github.com/jkeifer), [@parksjr](https://github.com/parksjr), and [@Xenocide122](https://github.com/Xenocide122) (all from [@Element84](https://github.com/Element84)) for creating the [rustac logo](https://raw.githubusercontent.com/stac-utils/rustac/refs/heads/main/img/rustac.svg) from an AI-generated image from this prompt:\n\n\u003e There is a library for working with STAC metadata that is written in rust called rustac: \u003chttps://github.com/stac-utils/rustac\u003e. That name sounds like the word \"rustic\", and is meant to envoke (sic) an image of \"a cabin and a glass of neat whisky\".\n\n## License\n\n**rustac-py** is dual-licensed under both the MIT license and the Apache license (Version 2.0).\nSee [LICENSE-APACHE](./LICENSE-APACHE) and [LICENSE-MIT](./LICENSE-MIT) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstac-utils%2Frustac-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstac-utils%2Frustac-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstac-utils%2Frustac-py/lists"}