Skip to content

stacs.queryables

A catalogue's declared queryables, and their comparison with what an API serves.

pgstac serves /collections/<id>/queryables from its own queryables table, never from the collection body. A catalogue declares the item properties its API should let clients filter on in stacs.toml, one JSON Schema fragment per property:

[queryables."lidarbc:delivery"]
type = "string"
title = "LidarBC delivery"

They are loaded for the catalogue's OWN collection and no other. pypgstac's loader replaces every row of a name that overlaps the collections it loads for, and the global row too, so a catalogue that named another's collection would narrow or remove that catalogue's queryable every time it registered. Rows for disjoint collections coexist.

Every refusal here is a declaration pgstac would not serve as written, which would read as drift on every verify.

QueryablesError

Bases: ValueError

A declaration pgstac would not serve as written, or a served one that cannot be compared.

parse_queryables(table)

{name: fragment} from the [queryables] table of a config. None means none.

Examples:

>>> parse_queryables({"lidarbc:delivery": {"type": "string"}})
{'lidarbc:delivery': {'type': 'string'}}
>>> parse_queryables({"datetime": {"type": "string"}})
Traceback (most recent call last):
...
stacs.queryables.QueryablesError: queryable 'datetime' is read by pgstac as a ...

queryables_document(declared)

The document pypgstac load_queryables reads: the fragments under properties.

Examples:

>>> queryables_document({"gsd": {"type": "number"}})["properties"]
{'gsd': {'type': 'number'}}

fragment_digest(fragment)

sha256 of a fragment in the form both sides are reduced to before comparing.

RFC 8785 over the same canonical form as item bodies, with one addition: pgstac serves enum as jsonb_agg(DISTINCT ...), deduplicated and reordered, so it is compared as a set.

Examples:

>>> fragment_digest({"enum": ["b", "a"]}) == fragment_digest({"enum": ["a", "b"]})
True

queryables_diff(declared, served)

(missing, changed): declared names the API does not serve, and those it serves with a different fragment.

Served names nobody declared are not reported: pgstac's global defaults and rows another loader wrote look the same from the API.

Examples:

>>> queryables_diff({"a": {"type": "string"}, "b": {"type": "string"}},
...                 {"b": {"type": "number"}, "id": {"type": "string"}})
(['a'], ['b'])