Core

Grid, errors, metrics, and the HTTP client — the foundational building blocks of the haystack-py library.

Grid

The universal Haystack message format. Grid holds columns, rows, and metadata. GridBuilder provides a fluent API for constructing grids programmatically.

Haystack Grid data structure.

The Grid is the fundamental data exchange unit in the Haystack HTTP API: a two-dimensional table with grid-level metadata, typed columns (each with optional metadata), and rows of tag dictionaries.

See: https://project-haystack.org/doc/docHaystack/Kinds#grid

class hs_py.grid.Col(name, meta=<factory>)[source]

Bases: object

A single column definition within a Grid.

Parameters:
name: str

Column name (must be a valid Haystack tag name).

meta: dict[str, Any]

Column-level metadata tags.

class hs_py.grid.Grid(meta=<factory>, cols=(), rows=())[source]

Bases: object

Two-dimensional tabular data with metadata.

Grids are immutable once constructed. Use GridBuilder for incremental construction.

Parameters:
meta: dict[str, Any]

Grid-level metadata tags.

cols: tuple[Col, ...]

Column definitions in display order.

rows: tuple[dict[str, Any], ...]

Row data as tag dicts keyed by column name.

property is_empty: bool

True if the grid has no rows.

property is_error: bool

True if this is an error grid (meta contains err marker).

property col_names: tuple[str, ...]

Column names in display order.

col(name)[source]

Look up a column by name.

Parameters:

name (str) – Column name to find.

Return type:

Col

Returns:

The matching Col instance.

Raises:

KeyError – If no column with name exists.

has_col(name)[source]

Check whether a column with name exists.

Parameters:

name (str) – Column name to check.

Return type:

bool

Returns:

True if the column exists.

classmethod make_empty()[source]

Return a cached empty grid with no columns or rows.

Return type:

Grid

Returns:

Singleton empty Grid.

classmethod make_error(dis, trace=None)[source]

Create an error grid.

Parameters:
  • dis (str) – Human-readable error description.

  • trace (str | None (default: None)) – Optional stack trace string.

Return type:

Grid

Returns:

A Grid with err marker in metadata.

classmethod make_rows(rows)[source]

Create a grid by inferring columns from row dicts.

Columns are ordered by first appearance across all rows.

Parameters:

rows (list[dict[str, Any]]) – List of tag dicts.

Return type:

Grid

Returns:

A Grid with columns inferred from keys.

classmethod make_rows_with_col_names(rows, col_names)[source]

Create a grid with pre-computed column names.

Skips the column inference scan of make_rows() when the caller already knows the column names (e.g. from a storage index).

Parameters:
Return type:

Grid

Returns:

A Grid with the given columns and rows.

class hs_py.grid.GridBuilder[source]

Bases: object

Mutable builder for constructing Grid instances.

set_meta(meta)[source]

Replace grid-level metadata tags.

Parameters:

meta (dict[str, Any]) – Tag dict to use as grid metadata.

Return type:

GridBuilder

Returns:

self for chaining.

add_meta(key, val=Marker)[source]

Add a single metadata tag.

Parameters:
  • key (str) – Tag name.

  • val (Any (default: Marker)) – Tag value (defaults to MARKER).

Return type:

GridBuilder

Returns:

self for chaining.

add_col(name, meta=None)[source]

Append a column definition.

Parameters:
  • name (str) – Column name.

  • meta (dict[str, Any] | None (default: None)) – Optional column-level metadata.

Return type:

GridBuilder

Returns:

self for chaining.

add_row(row)[source]

Append a data row.

Parameters:

row (dict[str, Any]) – Tag dict keyed by column name.

Return type:

GridBuilder

Returns:

self for chaining.

to_grid()[source]

Build and return an immutable Grid.

Return type:

Grid

Returns:

Constructed Grid instance.

Client

Async HTTP client implementing all standard Project Haystack operations. Handles SCRAM authentication, automatic 401 retry, and connection management.

Async Haystack HTTP API client.

Provides a high-level async client implementing the standard Project Haystack operations over HTTP using JSON encoding.

See: https://project-haystack.org/doc/docHaystack/HttpApi

class hs_py.client.Client(base_url, username='', password='', *, timeout=None, connector=None, tls=None, pythonic=True, accept_format='json')[source]

Bases: object

Async Haystack HTTP API client.

Usage:

async with Client("http://host/api", "user", "pass") as c:
    about = await c.about()  # returns list[dict] by default
    points = await c.read("point and sensor")
    raw_grid = await c.about(raw=True)  # returns Grid
Parameters:
  • base_url (str)

  • username (str)

  • password (str)

  • timeout (aiohttp.ClientTimeout | None)

  • connector (aiohttp.BaseConnector | None)

  • tls (TLSConfig | None)

  • pythonic (bool)

  • accept_format (str)

async close()[source]

Close the underlying HTTP session.

Return type:

None

async about(*, raw=False)[source]

Query server information.

Parameters:

raw (bool (default: False)) – If True, return the raw Grid regardless of the pythonic constructor setting.

Return type:

Grid | list[dict[str, Any]]

Returns:

Server metadata rows as list[dict] or Grid.

async ops(*, raw=False)[source]

Query available operations.

Parameters:

raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Supported ops rows as list[dict] or Grid.

async formats(*, raw=False)[source]

Query supported data formats.

Parameters:

raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Supported MIME type rows as list[dict] or Grid.

async read(filter, limit=None, *, raw=False)[source]

Read entities matching a filter expression.

Parameters:
  • filter (str) – Haystack filter string.

  • limit (int | None (default: None)) – Maximum number of entities to return.

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Matching entity rows as list[dict] or Grid.

async read_by_ids(ids, *, raw=False)[source]

Read entities by their identifiers.

Parameters:
  • ids (list[Ref]) – List of entity Refs to read.

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Matching entity rows as list[dict] or Grid.

async nav(nav_id=None, *, raw=False)[source]

Navigate the entity tree.

Parameters:
  • nav_id (str | None (default: None)) – Navigation ID for child lookup, or None for root.

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Navigation children as list[dict] or Grid.

async his_read(id, range, *, raw=False)[source]

Read time-series data for a single point.

Parameters:
  • id (Ref) – Ref of the historized point.

  • range (str) – Time range string (e.g. "today", "yesterday", "2024-01-01,2024-01-31").

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Time-series rows as list[dict] or Grid.

async his_read_batch(ids, range, *, raw=False)[source]

Read time-series data for multiple points.

Parameters:
  • ids (list[Ref]) – List of point Refs.

  • range (str) – Time range string.

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Time-series rows as list[dict] or Grid.

async his_write(id, items)[source]

Write time-series data to a single point.

Parameters:
  • id (Ref) – Ref of the historized point.

  • items (list[dict[str, Any]]) – List of dicts with ts and val keys.

Return type:

None

async his_write_batch(grid)[source]

Write time-series data for multiple points.

Parameters:

grid (Grid) – Pre-built grid with ts and v0/v1/… columns.

Return type:

None

async point_write_array(id, *, raw=False)[source]

Read the priority array of a writable point.

Parameters:
  • id (Ref) – Ref of the writable point.

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Priority array rows as list[dict] or Grid.

async point_write(id, level, val, who='', duration=None)[source]

Write to a priority array level.

Parameters:
  • id (Ref) – Ref of the writable point.

  • level (int) – Priority level 1-17.

  • val (Any) – Value to write, or None to release.

  • who (str (default: '')) – Identifier of who is making the write.

  • duration (Number | None (default: None)) – Optional duration for level 8 timed overrides.

Return type:

None

async watch_sub(ids, watch_dis, lease=None, *, raw=False)[source]

Create a new watch or add entities to an existing one.

Parameters:
  • ids (list[Ref]) – Entity Refs to watch.

  • watch_dis (str) – Display name for the watch.

  • lease (Number | None (default: None)) – Optional lease duration.

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Current entity state as list[dict] or Grid.

async watch_unsub(watch_id, ids)[source]

Remove entities from a watch.

Parameters:
  • watch_id (str) – Watch identifier.

  • ids (list[Ref]) – Entity Refs to unwatch.

Return type:

None

async watch_close(watch_id)[source]

Close a watch entirely.

Parameters:

watch_id (str) – Watch identifier to close.

Return type:

None

async watch_poll(watch_id, refresh=False, *, raw=False)[source]

Poll a watch for changes.

Parameters:
  • watch_id (str) – Watch identifier.

  • refresh (bool (default: False)) – If True, return full refresh of all watched entities.

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Changed (or all) entities as list[dict] or Grid.

async invoke_action(id, action, args=None, *, raw=False)[source]

Invoke an action on an entity.

Parameters:
  • id (Ref) – Ref of the target entity.

  • action (str) – Action name.

  • args (dict[str, Any] | None (default: None)) – Optional action arguments.

  • raw (bool (default: False)) – If True, return the raw Grid.

Return type:

Grid | list[dict[str, Any]]

Returns:

Action results as list[dict] or Grid.

Errors

Exception hierarchy for the haystack-py library.

Haystack exception hierarchy.

All exceptions derive from HaystackError for convenient catching.

exception hs_py.errors.AuthError[source]

Bases: HaystackError

Authentication handshake failure.

exception hs_py.errors.CallError(dis, grid)[source]

Bases: HaystackError

Server returned an error grid.

The grid attribute contains the full error grid with err marker, dis description, and optional errTrace.

Parameters:
Return type:

None

property dis: str

Human-readable error description.

property trace: str | None

Optional server stack trace.

exception hs_py.errors.HaystackError[source]

Bases: Exception

Base exception for all hs-py errors.

exception hs_py.errors.NetworkError[source]

Bases: HaystackError

Network-level communication failure.

Metrics

Observability hooks for monitoring client and server activity.

Optional metrics hooks for observability.

Provides a callback interface for tracking connection counts, message rates, latency, and errors. Users can plug in Prometheus, StatsD, or any metrics backend by supplying callbacks on MetricsHooks.

All hook invocations are guarded against exceptions so user callback errors never break the transport.

class hs_py.metrics.MetricsHooks(on_ws_connect=None, on_ws_disconnect=None, on_ws_message_sent=None, on_ws_message_recv=None, on_request=None, on_error=None)[source]

Bases: object

Optional callback hooks for transport-level metrics.

All callbacks are optional. When set, they are invoked at the corresponding transport event. Exceptions raised by callbacks are logged and silently suppressed.

Parameters:
  • on_ws_connect (Callable[[str], None] | None (default: None)) – Called with (remote_addr,) on new WebSocket connection.

  • on_ws_disconnect (Callable[[str], None] | None (default: None)) – Called with (remote_addr,) on WebSocket disconnect.

  • on_ws_message_sent (Callable[[str, int], None] | None (default: None)) – Called with (op, byte_count) after sending a message.

  • on_ws_message_recv (Callable[[str, int], None] | None (default: None)) – Called with (op, byte_count) after receiving a message.

  • on_request (Callable[[str, float], None] | None (default: None)) – Called with (op, duration_secs) after completing a request.

  • on_error (Callable[[str, str], None] | None (default: None)) – Called with (op, error_type) when an operation errors.

on_ws_connect: Callable[[str], None] | None

Called with (remote_addr,) on new WebSocket connection.

on_ws_disconnect: Callable[[str], None] | None

Called with (remote_addr,) on WebSocket disconnect.

on_ws_message_sent: Callable[[str, int], None] | None

Called with (op, byte_count) after sending a message.

on_ws_message_recv: Callable[[str, int], None] | None

Called with (op, byte_count) after receiving a message.

on_request: Callable[[str, float], None] | None

Called with (op, duration_secs) after completing a request.

on_error: Callable[[str, str], None] | None

Called with (op, error_type) when an operation errors.