Analytics class is the SDK surface for VectorShift’s observability data — the same runs, costs, latency, and traces you see in the platform dashboards, available as a chainable query API. Aggregate metrics, list and filter events, drill into a single trace, project a data table, or kick off a long-running export — directly from Python.
Prerequisites: Installed SDK · API key set · Python 3.10+.
Mental model
- Everything that runs on VectorShift emits events (the wire format calls them spans). An event is one Pipeline run, Chatbot message, KB fetch, Form submission, Session message, etc. — each carrying status, latency, token counts, costs, and a
trace_idthat links it to siblings. - There’s one entry point:
Analytics.query(...)returns an immutable, chainableQuery. Scope it by object and event kind, refine it with.where(...)and.group_by(...), then call a terminal (.count(),.sum(...),.events(),.table(...),.export(...)) to make the HTTP call and get a typed result. - Time scoping is a
.where()predicate —q.where(EventField.EVENT_START_TIME > cutoff). There is nosince=/start=/end=shortcut. Datetimes must be timezone-aware. Aggregations (sum,mean,percentile,raw_aggregate, …) require a lower time bound, or they raiseAnalyticsInvalidQuery. - Scope is a single object.
object=/object_ids=take one resource or one id. To analyse several, query each and merge client-side — passing more than one raisesAnalyticsInvalidQuery. - Single-object lookups live outside the chain:
Analytics.trace(trace_id),Analytics.event(event_id), andAnalytics.run(object=…, run_id=…). - Every terminal has an async sibling (
acount,aevents,asum,atable,aexport, …), andAnalytics.aquery(...)returns aQuerywhose terminals route to them.
Quick start
Scoping a query
| Scope | How | Use when |
|---|---|---|
| Org-wide | Analytics.query() | Account-level dashboards |
| All objects of a type | Analytics.query(object_type="pipeline") | ”All my pipelines this week” |
| A typed resource | Analytics.query(object=pipeline) | You have the Pipeline / Chatbot / Agent object in hand |
| A specific id | Analytics.query(object_type="chatbot", object_ids=["cb_123"]) | You only have the raw id |
| By event kind | Analytics.query(kinds=[EventKind.PIPELINE_RUN]) | Narrow to one span type |
object= reads its .id (and derives object_type from the class name) automatically. Scope resolves to a single object — object=[p1, p2] or object_ids=["a", "b"] raises AnalyticsInvalidQuery; loop and merge instead. Time is always a .where(EventField.EVENT_START_TIME …) predicate on top.
Terminals
| Terminal | Returns | What it does |
|---|---|---|
count() | EventCount | Number of matching events |
sum / mean / min / max | float | One-shot scalar aggregation over an AggregationField |
count_distinct | int | Distinct count |
percentile(field, n) | float | p50/p75/p95/p99 — latency / node_latency only |
group_by(...).<agg>(...) | dict[str, float] or AggregationResult | Bucketed aggregation (single-dim → flat dict, multi-dim → nested result) |
raw_aggregate(operations=[…]) | AggregationResult | Multiple metrics + group-by in one round-trip |
events(limit, offset) | EventPage | Paginated event list |
traces(limit, offset) | list[Trace] | Events grouped by trace_id |
table(columns=[…]) | DataTableResult | Column-projected rows |
export / export_and_wait | ExportTask | Long-running CSV / XLSX / JSON export |
Filtering
.where(...) accepts three intermixable forms:
- Equality kwargs —
q.where(status="failure", interface_type="chatbot"). Shortest for the common case. - Operator overloading on
EventField—q.where(EventField.EVENT_START_TIME > cutoff, EventField.ERROR_MESSAGE.matches("rate limit")). SQLAlchemy / Peewee style. - Dataclass helpers —
Filter(scope fields),FieldFilter(data columns), andFilterGroupfor OR groups vialogical_op=LogicalOp.OR.
.where() calls AND together. EventField.LATENCY, MODEL_ID, and NODE_TYPE are aggregation / group-by dimensions only — use them in .sum/.mean/.percentile or .group_by(...), not in .where(...).
What’s next
Reference
Every public method, filter, type, and enum.
Query basics example
Scope, time-bound, and run your first terminals.
Aggregations & group-by
Every aggregation terminal, single- and multi-dim.
