From 5a060d027dc3e0e80cf8f88c39dca8aca80fb348 Mon Sep 17 00:00:00 2001 From: Elephant Liu Date: Sat, 22 Nov 2025 11:36:29 +0800 Subject: [PATCH] more parse methods --- drow/parser.py | 35 +++++++++++++++++++++++++++-------- tests/test_parser.py | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/drow/parser.py b/drow/parser.py index 4ee5b4b..db964c7 100644 --- a/drow/parser.py +++ b/drow/parser.py @@ -51,6 +51,7 @@ def parse_query_response(self, resp: QueryResponse) -> QueryResult[T]: self.parse_error(resp) data = resp["data"] + result_type = data["resultType"] if data["resultType"] == "string": return self.parse_string(data) @@ -61,7 +62,21 @@ def parse_query_response(self, resp: QueryResponse) -> QueryResult[T]: if data["resultType"] == "vector": return self.parse_vector(data) - raise ParseError(f'unknown result type: {data["resultType"]}') + raise ParseError(f"unknown result type: {result_type}") + + def parse_query_response_as_vector( + self, resp: QueryResponse, + ) -> InstantVector[T]: + if resp["status"] == "error": + self.parse_error(resp) + + data = resp["data"] + result_type = data["resultType"] + + if data["resultType"] == "vector": + return self.parse_vector(data) + + raise ParseError(f"cannot parse {result_type} as vector") def parse_error(self, resp: ErrorResponse) -> Never: raise PrometheusError( @@ -111,26 +126,30 @@ def parse_scalar_point(self, data: PointData[str]) -> Point[T]: def parse_string(self, data: StringData) -> Point[str]: return Point(*data["result"]) - def parse_query_value_response(self, resp: QueryResponse) -> T: + def parse_query_response_as_value_point( + self, resp: QueryResponse, + ) -> Point[T]: if resp["status"] == "error": self.parse_error(resp) data = resp["data"] - - if data["resultType"] == "string": - return self.parse_value(data["result"][1]) + result_type = data["resultType"] if data["resultType"] == "scalar": - return self.parse_value(data["result"][1]) + return self.parse_scalar_point(data["result"]) if data["resultType"] == "vector": series_count = len(data["result"]) if series_count != 1: raise ParseError(f"series count incorrect: {series_count}") - return self.parse_value(data["result"][0]["value"][1]) + return self.parse_scalar_point(data["result"][0]["value"]) + + raise ParseError(f"cannot parse {result_type} as value") - raise ParseError(f'unknown result type: {data["resultType"]}') + def parse_query_response_as_value(self, resp: QueryResponse) -> T: + pt = self.parse_query_response_as_value_point(resp) + return pt.value def make_parser( diff --git a/tests/test_parser.py b/tests/test_parser.py index d15ea71..27b44c3 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -117,6 +117,9 @@ def test_success_string(self) -> None: assert isinstance(parsed, Point) self.assertEqual(parsed.value, "foo") + with self.assertRaises(ParseError): + parser.parse_query_response_as_value(resp) + def test_error(self) -> None: resp: ErrorResponse = { "status": "error", @@ -127,12 +130,24 @@ def test_error(self) -> None: with self.assertRaises(PrometheusError): parser.parse_query_response(resp) + with self.assertRaises(PrometheusError): + parser.parse_query_response_as_value(resp) + + with self.assertRaises(PrometheusError): + parser.parse_query_response_as_vector(resp) + + with self.assertRaises(PrometheusError): + parser.parse_query_range_response(resp) + def test_scalar_value(self) -> None: resp: SuccessResponse[ScalarData] = { "status": "success", "data": {"resultType": "scalar", "result": (1739529069.829, "5")}, } - self.assertEqual(parser.parse_query_value_response(resp), "5") + self.assertEqual(parser.parse_query_response_as_value(resp), "5") + + with self.assertRaises(ParseError): + parser.parse_query_response_as_vector(resp) def test_vector_value(self) -> None: resp: SuccessResponse[VectorData] = { @@ -149,9 +164,9 @@ def test_vector_value(self) -> None: ], }, } - self.assertEqual(parser.parse_query_value_response(resp), "6") + self.assertEqual(parser.parse_query_response_as_value(resp), "6") - def test_too_many_series_when_parse_value(self) -> None: + def test_vector_with_more_series(self) -> None: resp: SuccessResponse[VectorData] = { "status": "success", "data": { @@ -173,4 +188,15 @@ def test_too_many_series_when_parse_value(self) -> None: }, } with self.assertRaises(ParseError): - parser.parse_query_value_response(resp) + parser.parse_query_response_as_value(resp) + + vector = parser.parse_query_response_as_vector(resp) + self.assertEqual(len(vector.series), 2) + + s0 = vector.series[0] + self.assertEqual(s0.metric["job"], "foo") + self.assertEqual(s0.value.value, "1") + + s1 = vector.series[1] + self.assertEqual(s1.metric["job"], "bar") + self.assertEqual(s1.value.value, "0")