Store Client API#
Read-only interface for querying an Adapt data store (a directory created by
adapt init). Initialise StoreClient with the store root
path; it discovers collections, runs, scans, tracks, and every module’s product
table through the store’s catalogs — no file paths, no directory walking.
from adapt.api import StoreClient
client = StoreClient("/data/radar_output")
# Discover collections and runs
for run in client.runs("KLOT"): # newest first
print(run.run_id, run.status)
run = client.latest_run("KLOT")
# Complete scans only, identity-keyed (scan_id = sha256(raw bytes)[:16])
timeline = client.scan_timeline("KLOT", run.run_id)
with client.open_scan_raster("KLOT", run.run_id, timeline[-1].scan_id) as raster:
raster.dataset # fully in-memory xarray.Dataset
# Tracking
cells = client.cells(run.run_id, "KLOT")
history = client.track_history(run.run_id, "SOME_UID", "KLOT")
graph = client.track_graph(run.run_id, "SOME_UID", "KLOT") # split/merge component
# Any module's product table, with typed operator filters
severe = client.table("cell_tracks", "KLOT", run_id=run.run_id,
filters={"max_reflectivity": {"op": "gt", "value": 50.0}})
# Arbitrary read-only SQL (catalog attached as ``catalog``)
df = client.sql("SELECT COUNT(DISTINCT cell_uid) AS n FROM cells_by_scan", "KLOT")
client.close()
Cross-run queries (run_id=None) union across runs and every row carries its
run_id. Scan listings return complete scans only, so a consumer never
observes a half-written scan. scans_since provides a typed watermark for
live-follow polling.
StoreClient#
- class adapt.api.store_client.StoreClient(root)#
Bases:
objectRead API over one Adapt store root.
- Parameters:
root (str | Path)
- annotate(run_id, cell_uid, tag, note=None, collection=None)#
Attach a user tag to a cell — the client’s single write exception.
- Return type:
None- Parameters:
run_id (str)
cell_uid (str)
tag (str)
note (str | None)
collection (str | None)
- annotations(run_id, collection)#
- Return type:
DataFrame- Parameters:
run_id (str)
collection (str)
- artifacts(collection, run_id=None, artifact_type=None)#
Artifact metadata rows (no paths are needed to read them — see rasters).
- Return type:
list[dict]- Parameters:
collection (str)
run_id (str | None)
artifact_type (str | None)
- cells(run_id, collection)#
One run’s full per-scan cell table, time-ordered; empty before tracking.
- Return type:
DataFrame- Parameters:
run_id (str)
collection (str)
- cells_at_scan(run_id, scan_id, collection)#
All tracked-cell rows for one scan; empty before tracking ever ran.
- Return type:
DataFrame- Parameters:
run_id (str)
scan_id (str)
collection (str)
- close()#
Release every connection; the client is reusable after close.
- Return type:
None
- collections()#
Every registered collection.
- Return type:
list[Collection]
- is_pipeline_running(collection=None)#
True when any run (optionally of one collection) is in status running.
- Return type:
bool- Parameters:
collection (str | None)
- latest_run(collection=None)#
The most recently started run, or None on an empty store.
- Return type:
Run|None- Parameters:
collection (str | None)
- open_scan_raster(collection, run_id, scan_id, product='segmentation2d')#
One scan’s raster product, fully loaded in memory (no retained handle).
- Return type:
- Parameters:
collection (str)
run_id (str)
scan_id (str)
product (str)
- pipeline_progress(collection)#
The latest run’s lifecycle row plus its complete-scan count.
- Return type:
dict- Parameters:
collection (str)
- repository_info()#
Store-level summary: root, collections, run count.
- Return type:
dict
- run_config(run_id)#
The resolved configuration this run was executed with.
Parsed from the run provenance record (registry runs.config_json) — the single authoritative record of per-run settings such as
global_.tracking_fieldandreader.field_map. Keys use the InternalConfig field spelling (global_, notglobal).- Return type:
dict- Parameters:
run_id (str)
- run_tracking_field(run_id)#
The canonical field this run detected/projected/tracked on.
Interprets both provenance formats — the single home for this schema knowledge: - current runs record
global_.tracking_field; - legacy runs recordedglobal_.var_names.reflectivity(a nameknob whose value WAS the field the run tracked).
- Return type:
str- Parameters:
run_id (str)
- runs(collection=None)#
Runs, newest first (a documented ordering contract).
- Return type:
list[Run]- Parameters:
collection (str | None)
- scan_bundle(run_id, scan_id, collection)#
Everything for one COMPLETE scan, resolved through catalog links.
- Return type:
- Parameters:
run_id (str)
scan_id (str)
collection (str)
- scan_timeline(collection, run_id)#
The run’s ordered, complete-only scan timeline (the dashboard seam).
- Return type:
list[ScanRef]- Parameters:
collection (str)
run_id (str)
- scans(collection, run_id=None, start=None, end=None, limit=None)#
Complete scans, time-ordered;
run_id=Noneunions across runs.Cross-run rows always carry their
run_id— deduplication across reprocessed scans is the caller’s decision.- Return type:
list[Scan]- Parameters:
collection (str)
run_id (str | None)
start (datetime | None)
end (datetime | None)
limit (int | None)
- scans_since(collection, run_id, after=None)#
Live-follow: complete scans newer than the watermark (all when None).
- select(run_id, criteria, collection)#
Tracks of one run matching the FilterSpec (ranges, IN-lists, tags).
- Return type:
DataFrame- Parameters:
run_id (str)
criteria (FilterSpec)
collection (str)
- sql(query, collection)#
Arbitrary read-only SQL over products.db (catalog attached as
catalog).The scientists’ escape hatch: full SELECT generality over every module’s tables plus the
catalog.*discovery tables, on a read-only connection opened per call — writes are rejected by SQLite itself.- Return type:
DataFrame- Parameters:
query (str)
collection (str)
- table(name, collection, run_id=None, filters=None)#
Rows from one product table; every filter column is validated.
Filter values: scalar (equality), list/tuple (IN), or
{"op": "eq"|"gt"|"ge"|"lt"|"le"|"in", "value": ...}.- Return type:
DataFrame- Parameters:
name (str)
collection (str)
run_id (str | None)
filters (Mapping[str, Any] | None)
- tables(collection)#
Every product table’s frozen declaration (name, owner, granularity, keys).
- Return type:
DataFrame- Parameters:
collection (str)
- track(run_id, cell_uid, collection)#
- Return type:
- Parameters:
run_id (str)
cell_uid (str)
collection (str)
- track_events(run_id, cell_uid=None, collection=None)#
Lineage events for a run; with
cell_uid, edges touching that cell.- Return type:
DataFrame- Parameters:
run_id (str)
cell_uid (str | None)
collection (str | None)
- track_graph(run_id, cell_uid, collection)#
The full split/merge connected component around one cell.
Walks
cell_eventsedges (splits, merges, continuations) in both directions until closure, then returns every member cell’s track and every edge inside the component.- Return type:
TrackGraph- Parameters:
run_id (str)
cell_uid (str)
collection (str)
- track_history(run_id, cell_uid, collection)#
One cell’s per-scan rows across every scan it existed in, time-ordered.
- Return type:
DataFrame- Parameters:
run_id (str)
cell_uid (str)
collection (str)
- tracks(collection, run_id=None)#
The track population;
run_id=Noneunions across runs (rows carry it).- Return type:
DataFrame- Parameters:
collection (str)
run_id (str | None)
Domain Objects#
Immutable dataclasses returned by the client methods.
First-class domain objects for the Adapt store API.
- class adapt.api.domain.Collection(collection_id, source_kind, location_lat, location_lon)#
Bases:
objectA radar/site data domain; many runs, one catalog + products + objects.
- Parameters:
collection_id (str)
source_kind (str)
location_lat (float | None)
location_lon (float | None)
- collection_id: str#
- location_lat: float | None#
- location_lon: float | None#
- source_kind: str#
- class adapt.api.domain.Run(run_id, collection_id, status, started_at, ended_at, config_hash, pipeline_version)#
Bases:
objectA single pipeline execution (the ONE run lifecycle, from the registry).
- Parameters:
run_id (str)
collection_id (str)
status (str)
started_at (datetime)
ended_at (datetime | None)
config_hash (str)
pipeline_version (str)
- collection_id: str#
- config_hash: str#
- ended_at: datetime | None#
- pipeline_version: str#
- run_id: str#
- started_at: datetime#
- status: str#
- class adapt.api.domain.Scan(scan_id, run_id, collection_id, scan_time, source_file_name, status, start_time=None, end_time=None)#
Bases:
objectMetadata for one processed scan.
scan_idis the identity (join key); times are ordering/display metadata. Coverage times are per-source and may be absent.- Parameters:
scan_id (str)
run_id (str)
collection_id (str)
scan_time (datetime)
source_file_name (str)
status (str)
start_time (datetime | None)
end_time (datetime | None)
- collection_id: str#
- end_time: datetime | None = None#
- run_id: str#
- scan_id: str#
- scan_time: datetime#
- source_file_name: str#
- start_time: datetime | None = None#
- status: str#
- class adapt.api.domain.ScanBundle(scan, segmentation, cells, tracks=list())#
Bases:
objectAll data products for a single scan, loaded together.
- cells: DataFrame | None#
- segmentation: Dataset | None#
- class adapt.api.domain.ScanRaster(dataset, ref, product)#
Bases:
objectA scan’s raster product, fully loaded in memory — no file handle retained.
Closeable context manager:
close()releases the dataset reference; the underlying NetCDF file was already closed before construction, so a leaked ScanRaster costs memory, never file descriptors.- Parameters:
dataset (xr.Dataset)
ref (ScanRef)
product (str)
- close()#
- Return type:
None
- class adapt.api.domain.ScanRef(run_id, scan_id, scan_time)#
Bases:
objectOne position on a run’s scan timeline — identity plus display time.
- Parameters:
run_id (str)
scan_id (str)
scan_time (datetime)
- run_id: str#
- scan_id: str#
- scan_time: datetime#
- class adapt.api.domain.Track(run_id, cell_uid, first_seen, last_seen, n_scans, lifetime_s, origin_type, termination_type, max_area_km2, max_reflectivity_dbz)#
Bases:
objectLifecycle summary for one tracked cell (one row from cell_tracks).
- Parameters:
run_id (str)
cell_uid (str)
first_seen (datetime)
last_seen (datetime)
n_scans (int)
lifetime_s (float)
origin_type (str)
termination_type (str)
max_area_km2 (float)
max_reflectivity_dbz (float)
- cell_uid: str#
- first_seen: datetime#
- last_seen: datetime#
- lifetime_s: float#
- max_area_km2: float#
- max_reflectivity_dbz: float#
- n_scans: int#
- origin_type: str#
- run_id: str#
- termination_type: str#
FilterSpec#
Immutable filter compiled to a SQL WHERE clause by
select().
FilterSpec — API-level, immutable filter over a track population.
- class adapt.api.selection.FilterSpec(lifetime_min_s=None, lifetime_max_s=None, n_scans_min=None, max_area_min_km2=None, max_area_max_km2=None, max_refl_min_dbz=None, max_refl_max_dbz=None, origin_types=None, termination_types=None, required_tags=None, first_seen_after=None, first_seen_before=None)#
Bases:
objectImmutable filter over a run’s track population.
Each field is optional (None = no constraint). All constraints are ANDed. Compiles to SQL WHERE clause via
to_sql_where().The clause references
cell_trackscolumns:first_seen_time,last_seen_time,n_scans,max_area_sqkm,max_reflectivity,origin_type,termination_type.- Parameters:
lifetime_min_s (float | None)
lifetime_max_s (float | None)
n_scans_min (int | None)
max_area_min_km2 (float | None)
max_area_max_km2 (float | None)
max_refl_min_dbz (float | None)
max_refl_max_dbz (float | None)
origin_types (frozenset[str] | None)
termination_types (frozenset[str] | None)
required_tags (frozenset[str] | None)
first_seen_after (datetime | None)
first_seen_before (datetime | None)
- first_seen_after: datetime | None = None#
- first_seen_before: datetime | None = None#
- is_empty()#
Return True when no constraints are set (matches all tracks).
- Return type:
bool
- lifetime_max_s: float | None = None#
- lifetime_min_s: float | None = None#
- max_area_max_km2: float | None = None#
- max_area_min_km2: float | None = None#
- max_refl_max_dbz: float | None = None#
- max_refl_min_dbz: float | None = None#
- n_scans_min: int | None = None#
- origin_types: frozenset[str] | None = None#
- required_tags: frozenset[str] | None = None#
- termination_types: frozenset[str] | None = None#
- to_sql_where()#
Compile filter to a SQL WHERE clause and positional parameter list.
- Return type:
tuple[str,list]- Returns:
clause (str) – SQL fragment starting with
WHEREif any constraints exist, empty string otherwise.params (list) – Positional parameters matching
?placeholders in clause.