Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Use the infrastore CLI

infrastore loads time series from CSV files and inspects a store, talking directly to the on-disk .nc + .nc.sqlite pair (no gRPC server required). For the full command and descriptor reference, see CLI Reference.

1. Build the Binary

cargo build -p infrastore-cli      # debug build at target/debug/infrastore
# or a release build:
cargo build -p infrastore-cli --release

The examples below assume infrastore is on your PATH (or use ./target/debug/infrastore).

2. Describe the Data

Numeric values live in a CSV; everything that does not fit a flat grid (owner, name, type, dtype, resolution, initial timestamp, units, features) lives in a descriptor JSON. Print a starting point for any type with template:

infrastore template single > load.json       # print an example descriptor to edit

Edit it to point at your data and metadata:

{
  "owner_id": 42,
  "owner_type": "Generator",
  "owner_category": "component",
  "name": "load",
  "type": "single",
  "dtype": "f64",
  "units": "MW",
  "csv": "load.csv",
  "has_header": true,
  "initial_timestamp": "2024-01-01T00:00:00Z",
  "resolution": "1h",
  "features": {
    "model_year": 2030
  }
}
# load.csv
value
100.0
101.5
103.0
104.2
102.8
101.0

The descriptor rejects unknown keys, so a typo (resolutionn) is a hard error rather than a silently ignored setting.

3. Add It to a Store

infrastore --store demo.nc add --descriptor load.json

The store (demo.nc and its demo.nc.sqlite catalog) is created on first add. A descriptor may also be a JSON array of objects to add many series in one transaction. --csv overrides the descriptor's csv path, but only for a single-series descriptor: with an array of two or more objects it errors (--csv cannot be used with an array descriptor).

4. Read It Back

infrastore follows an output convention: a global -f/--format with table (default), json, and csv. Only the read commands (list, get, info) honor it; add, remove, transform, and template accept the flag but ignore it and print plain text.

infrastore --store demo.nc list                                       # what's in the store
infrastore --store demo.nc list --name-glob 'load_*'                  # name pattern (SQLite GLOB)
infrastore --store demo.nc get  --owner-id 42 --name load             # pretty table
infrastore --store demo.nc -f csv  get  --owner-id 42 --name load     # round-trippable CSV
infrastore --store demo.nc -f json info --owner-id 42 --name load     # metadata + stats
infrastore --store demo.nc -f csv  export --dir out/                  # one file per series

export is the bulk read-direction inverse of add: every series the selector matches is written to its own CSV or JSON file under --dir (or to stdout when exactly one matches). Setting INFRASTORE_STORE in the environment stands in for --store, and destructive commands (remove, clear, replace-owner, rename, copy) accept --dry-run to preview their effect.

info reports metadata plus stats over the values: min/max/mean for numeric dtypes, or true_count/false_count when dtype is bool, and always num_elements.

get/info/remove select a single series with --owner-id, --owner-category, --name, --type, --resolution, and repeated --feature key=value (--feature is the only repeatable one); if more than one series matches, infrastore lists the candidates so you can narrow the query. The owner is the (owner_id, owner_category) pair, so a component and a supplemental attribute may share a numeric id — add --owner-category (component / supplemental_attribute) to disambiguate. Large series truncate in table output — pass --limit N or --full.

--time-range START..END on get takes two timestamps (RFC3339 or epoch-ms), not a duration:

infrastore --store demo.nc get --owner-id 42 --name load \
  --time-range 2024-01-01T01:00:00Z..2024-01-01T03:00:00Z

Beware that inputs and outputs are spelled differently. You type the short, lowercase forms (--type single, --owner-category component), but list/get/info print the canonical CamelCase names (SingleTimeSeries, Component). Both spellings are accepted as input, so -f json list output can be fed back into a selector unchanged; just don't expect the rendered value to string-match what you typed.

5. Forecasts

All five writable types work (single, non_sequential, deterministic, probabilistic, scenarios). infrastore template deterministic prints a descriptor to edit, but it is plain JSON and says nothing about the data layout, so here is the rule:

Forecast CSVs are a flat, row-major stream of values with no structure of their own. The count must equal the product of the type's shape:

TypeShape
deterministic[H, count, *element_shape]
probabilistic[num_percentiles, H, count, *E]
scenarios[scenario_count, H, count, *E]

H = horizon / resolution — with the template's "horizon": "24h", "resolution": "1h", and "count": 7, a scalar deterministic needs exactly 24 * 7 = 168 values (plus the header row that has_header: true skips). Use -f json to read the flat values back at full fidelity. get -f csv on a forecast emits timestamped analysis rows instead — one row per (window, step) with issue_time/target_time columns and one value column per percentile or scenario — so it is not re-ingestible by add (static series' get -f csv still round-trips).

DeterministicSingleTimeSeries is not added from CSV — store a SingleTimeSeries, then derive it. transform takes no selector: it rewrites every SingleTimeSeries in the store. --horizon must fit inside each one (horizon / resolution steps must not exceed its length), so with the 6-row hourly load above, a 24-hour horizon fails and a 3-hour one works:

infrastore --store demo.nc transform --horizon 3h --interval 1h

The derived series keeps the source's owner, name, and resolution, so load now matches two entries and a bare selector becomes ambiguous. Disambiguate with --type:

infrastore --store demo.nc get --owner-id 42 --name load --type single
infrastore --store demo.nc get --owner-id 42 --name load --type deterministic_single

Notes

  • The CLI writes locally; there is no remote/gRPC mode yet (store access is isolated so one can be added later).
  • Output is colored (green table headers) only when stdout is a terminal; it is plain when piped/redirected or when NO_COLOR is set, so -f json/-f csv stay clean for other tools.
  • --log-level (or RUST_LOG) controls logging; the default is quiet (warn).
  • The .nc and .nc.sqlite files are one artifact — move, copy, and delete them together.