stacs¶
Register a STAC catalogue into pgstac and prove it arrived.
stacs works on a catalogue after its items exist. It does not read source data or
build items: that belongs to the repository that owns the source. Anything source-agnostic
that is done to a published catalogue belongs here.
Status: pre-release. Extracted from
stac_dem_bc, where the registration and verification code has run against a 102,460-item collection.
What it does¶
- Verify what a STAC API serves against what is published: item id sets compared in both directions, and every item body compared by digest. Never by count: a STAC API omits ids it does not have without reporting an error, so equal counts can hide unequal sets. A body that could not be read is an error, never "unchanged".
- Register with upserts only, collection before items. Nothing deletes.
driftregisters only what the API is missing or serves differently, which keeps it stateless: a skipped run is picked up by the next one. Every write is followed by a check that the API now serves the body that was sent. - Audit items before they are registered: each names the collection it is going into,
and carries the asset keys the catalogue declares (
require) and none it has retired (forbid). - Validate items with
pystac.
Body digests are SHA-256 over RFC 8785 (JCS)
canonical JSON, with links removed (the API rewrites them) and null members dropped
(pgstac strips them). research/pgstac_round_trip.md
records what pgstac changes between load and serve, and why each rule exists.
Install¶
Managed with uv. Install from git rather than PyPI: the
stacs name on PyPI belongs to an unrelated, archived project.
[tool.uv.sources]
stacs = { git = "https://github.com/NewGraphEnvironment/stacs", tag = "v0.2.0" }
Without uv: pip install "stacs @ git+https://github.com/NewGraphEnvironment/stacs@v0.2.0".
Development¶
uv sync
uv run pytest
The tests run offline: a stub STAC API on loopback, a stub ssh that runs the remote
script locally against a fake pypgstac, and a guard that refuses any DNS lookup outside
loopback.