Skip to content
This repository was archived by the owner on Aug 14, 2025. It is now read-only.

Commit 7ea977b

Browse files
committed
feat: implement query_metrics
Signed-off-by: Charlie Doern <[email protected]>
1 parent 028a8dd commit 7ea977b

File tree

7 files changed

+270
-0
lines changed

7 files changed

+270
-0
lines changed

src/llama_stack_client/resources/telemetry.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
telemetry_query_traces_params,
1313
telemetry_get_span_tree_params,
1414
telemetry_save_spans_to_dataset_params,
15+
telemetry_query_metrics_params,
1516
)
1617
from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
1718
from .._utils import maybe_transform, async_maybe_transform
@@ -27,11 +28,15 @@
2728
from ..types.trace import Trace
2829
from .._base_client import make_request_options
2930
from ..types.event_param import EventParam
31+
32+
from ..types.metric_label_matcher_param import MetricLabelMatcherParam
33+
from ..types.metric_query_type_param import MetricQueryTypeParam
3034
from ..types.query_condition_param import QueryConditionParam
3135
from ..types.telemetry_get_span_response import TelemetryGetSpanResponse
3236
from ..types.telemetry_query_spans_response import TelemetryQuerySpansResponse
3337
from ..types.telemetry_query_traces_response import TelemetryQueryTracesResponse
3438
from ..types.telemetry_get_span_tree_response import TelemetryGetSpanTreeResponse
39+
from ..types.telemetry_query_metrics_response import TelemetryQueryMetricsResponse
3540

3641
__all__ = ["TelemetryResource", "AsyncTelemetryResource"]
3742

@@ -377,6 +382,66 @@ def save_spans_to_dataset(
377382
cast_to=NoneType,
378383
)
379384

385+
def query_metrics(
386+
self,
387+
*,
388+
metric_name: str,
389+
start_time: int,
390+
end_time: int | None = None,
391+
granularity: str | None = "1d",
392+
query_type: MetricQueryTypeParam = MetricQueryTypeParam.RANGE,
393+
label_matchers: Iterable[MetricLabelMatcherParam] | None = None,
394+
extra_headers: Headers | None = None,
395+
extra_query: Query | None = None,
396+
extra_body: Body | None = None,
397+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
398+
) -> TelemetryQueryMetricsResponse:
399+
"""
400+
Query metrics.
401+
402+
Args:
403+
metric_name: The name of the metric to query
404+
405+
start_time: The start time for the query (Unix timestamp)
406+
407+
end_time: (Optional) The end time for the query (Unix timestamp)
408+
409+
granularity: (Optional) The granularity of the query (e.g., '1d', '1h')
410+
411+
query_type: (Optional) The type of metric query to perform
412+
413+
label_matchers: (Optional) Label matchers to filter the metrics
414+
415+
extra_headers: Send extra headers
416+
417+
extra_query: Add additional query parameters to the request
418+
419+
extra_body: Add additional JSON properties to the request
420+
421+
timeout: Override the client-level default timeout for this request, in seconds
422+
"""
423+
return self._post(
424+
f"/v1/telemetry/metrics/{metric_name}",
425+
body=maybe_transform(
426+
{
427+
"start_time": start_time,
428+
"end_time": end_time,
429+
"granularity": granularity,
430+
"query_type": query_type.value if query_type else None,
431+
"label_matchers": label_matchers,
432+
},
433+
telemetry_query_metrics_params.TelemetryQueryMetricsParams,
434+
),
435+
options=make_request_options(
436+
extra_headers=extra_headers,
437+
extra_query=extra_query,
438+
extra_body=extra_body,
439+
timeout=timeout,
440+
post_parser=DataWrapper[TelemetryQueryMetricsResponse]._unwrapper,
441+
),
442+
cast_to=cast(Type[TelemetryQueryMetricsResponse], DataWrapper[TelemetryQueryMetricsResponse]),
443+
)
444+
380445

381446
class AsyncTelemetryResource(AsyncAPIResource):
382447
@cached_property
@@ -560,6 +625,68 @@ async def log_event(
560625
),
561626
cast_to=NoneType,
562627
)
628+
629+
630+
async def query_metrics(
631+
self,
632+
*,
633+
metric_name: str,
634+
start_time: int,
635+
end_time: int | None = None,
636+
granularity: str | None = "1d",
637+
query_type: MetricQueryTypeParam = MetricQueryTypeParam.RANGE,
638+
label_matchers: Iterable[MetricLabelMatcherParam] | None = None,
639+
extra_headers: Headers | None = None,
640+
extra_query: Query | None = None,
641+
extra_body: Body | None = None,
642+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
643+
) -> TelemetryQueryMetricsResponse:
644+
"""
645+
Query metrics.
646+
647+
Args:
648+
metric_name: The name of the metric to query
649+
650+
start_time: The start time for the query (Unix timestamp)
651+
652+
end_time: (Optional) The end time for the query (Unix timestamp)
653+
654+
granularity: (Optional) The granularity of the query (e.g., '1d', '1h')
655+
656+
query_type: (Optional) The type of metric query to perform
657+
658+
label_matchers: (Optional) Label matchers to filter the metrics
659+
660+
extra_headers: Send extra headers
661+
662+
extra_query: Add additional query parameters to the request
663+
664+
extra_body: Add additional JSON properties to the request
665+
666+
timeout: Override the client-level default timeout for this request, in seconds
667+
"""
668+
return await self._post(
669+
f"/v1/telemetry/metrics/{metric_name}",
670+
body=await async_maybe_transform(
671+
{
672+
"start_time": start_time,
673+
"end_time": end_time,
674+
"granularity": granularity,
675+
"query_type": query_type.value if query_type else None,
676+
"label_matchers": label_matchers,
677+
},
678+
telemetry_query_metrics_params.TelemetryQueryMetricsParams,
679+
),
680+
options=make_request_options(
681+
extra_headers=extra_headers,
682+
extra_query=extra_query,
683+
extra_body=extra_body,
684+
timeout=timeout,
685+
post_parser=DataWrapper[TelemetryQueryMetricsResponse]._unwrapper,
686+
),
687+
cast_to=cast(Type[TelemetryQueryMetricsResponse], DataWrapper[TelemetryQueryMetricsResponse]),
688+
)
689+
563690

564691
async def query_spans(
565692
self,
@@ -742,6 +869,9 @@ def __init__(self, telemetry: TelemetryResource) -> None:
742869
self.query_traces = to_raw_response_wrapper(
743870
telemetry.query_traces,
744871
)
872+
self.query_metrics = to_raw_response_wrapper(
873+
telemetry.query_metrics,
874+
)
745875
self.save_spans_to_dataset = to_raw_response_wrapper(
746876
telemetry.save_spans_to_dataset,
747877
)
@@ -769,6 +899,9 @@ def __init__(self, telemetry: AsyncTelemetryResource) -> None:
769899
self.query_traces = async_to_raw_response_wrapper(
770900
telemetry.query_traces,
771901
)
902+
self.query_metrics = async_to_raw_response_wrapper(
903+
telemetry.query_metrics,
904+
)
772905
self.save_spans_to_dataset = async_to_raw_response_wrapper(
773906
telemetry.save_spans_to_dataset,
774907
)
@@ -796,6 +929,9 @@ def __init__(self, telemetry: TelemetryResource) -> None:
796929
self.query_traces = to_streamed_response_wrapper(
797930
telemetry.query_traces,
798931
)
932+
self.query_metrics = to_streamed_response_wrapper(
933+
telemetry.query_metrics,
934+
)
799935
self.save_spans_to_dataset = to_streamed_response_wrapper(
800936
telemetry.save_spans_to_dataset,
801937
)
@@ -823,6 +959,9 @@ def __init__(self, telemetry: AsyncTelemetryResource) -> None:
823959
self.query_traces = async_to_streamed_response_wrapper(
824960
telemetry.query_traces,
825961
)
962+
self.query_metrics = async_to_streamed_response_wrapper(
963+
telemetry.query_metrics,
964+
)
826965
self.save_spans_to_dataset = async_to_streamed_response_wrapper(
827966
telemetry.save_spans_to_dataset,
828967
)

src/llama_stack_client/types/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@
139139
from .vector_db_register_response import VectorDBRegisterResponse as VectorDBRegisterResponse
140140
from .vector_db_retrieve_response import VectorDBRetrieveResponse as VectorDBRetrieveResponse
141141
from .scoring_score_batch_response import ScoringScoreBatchResponse as ScoringScoreBatchResponse
142+
from .telemetry_query_metrics_params import TelemetryQueryMetricsParams as TelemetryQueryMetricsParams
143+
from .telemetry_query_metrics_response import TelemetryQueryMetricsResponse as TelemetryQueryMetricsResponse
142144
from .telemetry_query_spans_params import TelemetryQuerySpansParams as TelemetryQuerySpansParams
143145
from .vector_store_delete_response import VectorStoreDeleteResponse as VectorStoreDeleteResponse
144146
from .vector_store_search_response import VectorStoreSearchResponse as VectorStoreSearchResponse
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from __future__ import annotations
2+
3+
from typing import Union, Iterable
4+
from typing_extensions import TypedDict
5+
6+
from .metric_label_operator_param import MetricLabelOperator
7+
8+
__all__ = ["MetricLabelMatcherParam"]
9+
10+
class MetricLabelMatcherParam(TypedDict, total=False):
11+
"""A matcher for filtering metrics by label values.
12+
:param name: The name of the label to match
13+
:param value: The value to match against
14+
:param operator: The comparison operator to use for matching
15+
"""
16+
17+
name: str
18+
value: str
19+
operator: MetricLabelOperator = MetricLabelOperator.EQUALS
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from enum import Enum
2+
3+
class MetricLabelOperator(Enum):
4+
"""Operators for matching metric labels.
5+
:cvar EQUALS: Label value must equal the specified value
6+
:cvar NOT_EQUALS: Label value must not equal the specified value
7+
:cvar REGEX_MATCH: Label value must match the specified regular expression
8+
:cvar REGEX_NOT_MATCH: Label value must not match the specified regular expression
9+
"""
10+
11+
EQUALS = "="
12+
NOT_EQUALS = "!="
13+
REGEX_MATCH = "=~"
14+
REGEX_NOT_MATCH = "!~"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from enum import Enum
2+
3+
class MetricQueryTypeParam(Enum):
4+
"""The type of metric query to perform.
5+
:cvar RANGE: Query metrics over a time range
6+
:cvar INSTANT: Query metrics at a specific point in time
7+
"""
8+
9+
RANGE = "range"
10+
INSTANT = "instant"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing import Union, Iterable
6+
from typing_extensions import Literal, Required, TypedDict
7+
8+
from .metric_label_matcher_param import MetricLabelMatcherParam
9+
from .metric_query_type_param import MetricQueryTypeParam
10+
11+
__all__ = ["TelemetryQueryMetricsParams"]
12+
13+
14+
class TelemetryQueryMetricsParams(TypedDict, total=False):
15+
metric_name: Required[str]
16+
"""The name of the metric to query"""
17+
18+
start_time: Required[int]
19+
"""The start time for the query (Unix timestamp)"""
20+
21+
end_time: int
22+
"""(Optional) The end time for the query (Unix timestamp)"""
23+
24+
granularity: str
25+
"""(Optional) The granularity of the query (e.g., '1d', '1h')"""
26+
27+
query_type: MetricQueryTypeParam
28+
"""(Optional) The type of metric query to perform"""
29+
30+
label_matchers: Iterable[MetricLabelMatcherParam]
31+
"""(Optional) Label matchers to filter the metrics"""
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing import Dict, List, Union, Optional
4+
from datetime import datetime
5+
from typing_extensions import TypeAlias
6+
7+
from .._models import BaseModel
8+
9+
__all__ = ["TelemetryQueryMetricsResponse", "MetricSeries", "MetricLabel", "MetricDataPoint"]
10+
11+
12+
class MetricLabel(BaseModel):
13+
"""A label associated with a metric.
14+
:param name: The name of the label
15+
:param value: The value of the label
16+
"""
17+
18+
name: str
19+
"""The name of the label"""
20+
21+
value: str
22+
"""The value of the label"""
23+
24+
25+
class MetricDataPoint(BaseModel):
26+
"""A single data point in a metric time series.
27+
:param timestamp: Unix timestamp when the metric value was recorded
28+
:param value: The numeric value of the metric at this timestamp
29+
"""
30+
31+
timestamp: int
32+
"""Unix timestamp when the metric value was recorded"""
33+
34+
value: float
35+
"""The numeric value of the metric at this timestamp"""
36+
37+
38+
class MetricSeries(BaseModel):
39+
"""A time series of metric data points.
40+
:param metric: The name of the metric
41+
:param labels: List of labels associated with this metric series
42+
:param values: List of data points in chronological order
43+
"""
44+
45+
metric: str
46+
"""The name of the metric"""
47+
48+
labels: List[MetricLabel]
49+
"""List of labels associated with this metric series"""
50+
51+
values: List[MetricDataPoint]
52+
"""List of data points in chronological order"""
53+
54+
55+
TelemetryQueryMetricsResponse: TypeAlias = List[MetricSeries]

0 commit comments

Comments
 (0)