Catalog search¶
The UmbraCatalog is the entry point for discovery: it searches Umbra's static
STAC catalog by area, date range, product type, place name, or polygon, and can
read through a local index for fast, repeatable, offline queries.
UmbraCatalog
¶
UmbraCatalog(bucket=S3_BUCKET, region=S3_REGION, session=None, *, token=None, archive_url=CANOPY_ARCHIVE_URL, collections=None)
Client for searching Umbra SAR data.
By default this searches Umbra's open data by crawling the public S3
bucket (a static STAC catalog with no search API). Pass a Canopy token
and the same :meth:search interface instead queries Umbra's
authenticated commercial archive over its real STAC API
(:data:~umbra_py.constants.CANOPY_ARCHIVE_URL)::
# open data (default) -- no account needed
UmbraCatalog().search(area="Centerfield", limit=5)
# commercial archive -- same call, one extra argument
UmbraCatalog(token="...").search(bbox=bbox, start="2024", limit=5)
Both paths yield :class:~umbra_py.UmbraItem objects, so every downstream
verb (download, quicklook, change, chips, ...) works unchanged against
either archive. That is the funnel made literal: a user onboarded on the
free bucket is already holding the tool they'd use as a paying customer.
Get a token from https://docs.canopy.umbra.space/.
search
¶
search(*, bbox=None, intersects=None, start=None, end=None, product_types=None, area=None, fuzzy=False, polarizations=None, min_incidence=None, max_incidence=None, max_resolution=None, limit=None, max_per_task=None)
Yield items matching the filters.
Parameters¶
bbox:
(min_lon, min_lat, max_lon, max_lat) footprint filter.
intersects:
A polygon geometry (the exterior-ring form from
:func:umbra_py._geometry.parse_geometry); keep only items whose
footprint intersects it. A tighter spatial filter than the
rectangular bbox -- the standard STAC intersects. Combines
with bbox (both must match) when both are given.
start, end:
Inclusive acquisition-date bounds. Accepts date /
datetime objects or ISO YYYY-MM-DD strings. The walker
still has to list each task to discover what's published in
range, so even a narrow window takes a few seconds; provide
limit to stop as soon as you have enough.
product_types:
Keep only items exposing at least one of these assets
(e.g. ["GEC"]).
area:
Case-insensitive substring matched against each
sar-data/tasks/<task>/ directory name. Umbra files every
pass of a site under one named task directory (e.g.
"Centerfield, Utah"), so area="centerfield" returns
just that site's acquisitions. Non-matching task directories
are skipped before they're listed, so this also makes the
search much faster -- the ergonomic way to gather the
co-located passes a change composite needs.
fuzzy:
Widen area from a literal substring to a deterministic
token-wise fuzzy match (:func:umbra_py.fuzzy.task_matches):
word-order- and punctuation-independent, tolerant of a small
typo, and a strict superset of the substring match (it never
drops a result). So area="utah centerfield" or
area="centrfield" still reaches "Centerfield, Utah".
No model call -- the C1 deterministic first step.
polarizations:
Keep only items exposing at least one of these polarizations
(case-insensitive, e.g. ["VV"]) -- the SAR-native filter that
keeps a change comparison like-with-like (HH and VV image different
physics). An item with no polarization metadata is excluded.
min_incidence, max_incidence:
Inclusive bounds (degrees) on the view incidence angle
(:attr:UmbraItem.incidence_angle). An item with no incidence
metadata is excluded when either bound is set.
max_resolution:
Keep only items at least this fine -- both range and azimuth
resolution <= max_resolution metres. An item missing either
resolution value is excluded. See :meth:UmbraItem.matches_filters
for the exact acquisition-property semantics (a set filter excludes
items lacking that property, matching the STAC Query extension).
limit:
Stop after yielding this many items.
max_per_task:
Cap the number of items yielded from any one
sar-data/tasks/<task>/ directory. Each task is a tasking
campaign over the same area, so max_per_task=1 swaps the
usual "every revisit of a few sites" output for "one
acquisition per distinct site" -- much better diversity on a
map.
Notes¶
When this catalog was created with a Canopy token, the search runs
against Umbra's commercial STAC API instead of the open bucket. The
filters mean the same thing; bbox and the date bounds are sent to
the API, while product_types and area/fuzzy are applied to
the returned items (exactly as they are on the open-bucket path), so the
interface is identical across both archives.
get_item
¶
Fetch a single acquisition from the Canopy commercial archive by id.
The keyed-retrieval complement to :meth:search's listing: given a STAC
item id, return that one :class:~umbra_py.UmbraItem, or None when the
archive has no such item. It is implemented with the STAC API ids
search extension over the same /archive/search endpoint
:meth:search already POSTs to -- POST {"ids": [item_id], "limit": 1}
-- so it introduces no new endpoint to guess and stays offline-testable
against a mocked API, exactly like the search path. Bearer auth, the
helpful 401/403 "token rejected" message and the 500 wrap are all
inherited from :meth:_archive_page.
Requires a Canopy token. The open bucket is a static catalog with no
id-to-item index, so a keyed lookup isn't meaningful there -- resolve an
open-data item from its sidecar URL instead
(:meth:UmbraItem.from_dict / umbra info <url>) or from a built index
(:meth:umbra_py.CatalogIndex.get).