Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions drow/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down
34 changes: 30 additions & 4 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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] = {
Expand All @@ -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": {
Expand All @@ -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")