Example: read a node's info and telemetry
This article refers to SDK version v0.5.0. The current SDK version is N/A.
Overview
node_info.py reads everything known about one node: identity, version, GPS, alarms, status, and its latest live telemetry sample, in a single script. It's the shape of query a support tool, an inventory sync, or a monitoring dashboard's "node detail" view needs.
Beyond the typed resources, it also demonstrates reading data that has no dedicated resource method yet, through the client's low-level request(...) escape hatch.
Get the script
Download node_info.py from the SDK's examples/ directory. If you haven't installed the SDK yet, see Getting started.
Set up credentials
The script reads the four Barbara API Credentials from environment variables, or from a .env file placed next to it (loaded automatically, or pointed at with --env-file). See Set up credentials in the Hello World walkthrough for the full picture, and Authenticate for what each credential is.
Walk through the code
resolve_node() accepts either an internal _id or a Barbara ID (deviceName), and dispatches accordingly:
INTERNAL_ID_RE = re.compile(r"^[0-9a-f]{24}$")
def resolve_node(client: BarbaraClient, identifier: str) -> Node:
if INTERNAL_ID_RE.match(identifier):
return client.nodes.get(identifier)
return client.nodes.resolve(identifier)
An internal id is always a 24-character hexadecimal string, so a regex match is enough to tell the two apart without an extra request.
get_static_info() pulls a node's stable configuration straight from node.raw:
def get_static_info(node: Node) -> dict[str, Any]:
raw = node.raw
return {
"identity": {"deviceName": raw.get("deviceName"), "name": raw.get("name"), ...},
"version": raw.get("deviceVersion"),
"config": raw.get("deviceConfig"),
"gps": raw.get("gps"),
"alarms": raw.get("alarms"),
"status": raw.get("status"),
}
Every entity the SDK returns keeps the full API response on .raw, so fields the typed Node model hasn't wrapped yet, like deviceVersion or gps, are still reachable without an extra request.
get_telemetry() reads the node's latest sample, which has no typed resource method yet:
def get_telemetry(client: BarbaraClient, node_id: str) -> Optional[dict[str, Any]]:
try:
data = unwrap(client.request("GET", f"/api/v2/devices/{node_id}/telemetries/last"))
except BarbaraApiError:
return None
return dict(data) if data else None
client.request(...) is the same authenticated, token-refreshing method every typed resource method is built on, see request in the Reference, and barbara.utils.unwrap peels off the API's response envelope. A BarbaraApiError here is treated as "no sample yet" rather than a hard failure, since an older agent may not have reported a /v2 telemetry sample.
main() follows the same fail-fast login pattern as every example, then resolves the node and handles a lookup miss explicitly:
try:
node = resolve_node(client, args.node)
except BarbaraNotFoundError:
raise SystemExit(f"No node found matching '{args.node}'")
It assembles nodeId, static, and telemetry into one dict and prints it as indented JSON.
Run it
python node_info.py my-node-01
python node_info.py 64f0aaaaaaaaaaaaaaaaaaaa
The single argument accepts either form: a Barbara ID or an internal _id.
Try it
Run it against a node you know is online, then one that's offline, and compare the telemetry block: it comes back null if the node hasn't reported a sample yet. Then pass a name that doesn't exist and read the resulting BarbaraNotFoundError message, that's the same error path a typo in a script or a decommissioned node would trigger. If you have jq installed, pipe the output through it to pull out a single field: python node_info.py my-node-01 | jq .telemetry.cpu.
Extend it
- Surface more fields.
get_static_infoonly prints a handful of keys, every field the API returns is onnode.raw, not just the ones this script picks out. Add the fields your own use case needs. - Poll it on an interval. Wrap the body in
while True: ...; time.sleep(5)to turn this into a simple live dashboard for one node. - Add the node's group membership.
client.nodes.list_groups(node.id)returns the list of groups a node belongs to; a node can belong to more than one. Network interfaces are wrapped the same way, seeclient.nodes.networkand Network audit for the equivalent script.
Summary
You read a node's full static configuration and its live telemetry in one script, combining a typed resource call with the request(...) escape hatch for data the SDK hasn't wrapped yet.
That escape hatch is what keeps the SDK useful even where its typed coverage stops, any endpoint the Barbara API exposes is reachable the same way.
To turn a single-node read into a fleet-wide check, continue to Check Barbara Core updates. For the full method list, see client.nodes in the Reference.