From 64cbe3f41e0fefd202ae5910e847094d74935a8d Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Thu, 19 Aug 2021 15:40:24 -0700 Subject: [PATCH] Handle value types for results (#20358) * Handle value types for results * update test * lint * comprehension * more precis * fix test --- sdk/monitor/azure-monitor-query/CHANGELOG.md | 1 + .../azure/monitor/query/_helpers.py | 12 ++++++- .../azure/monitor/query/_models.py | 4 +-- .../tests/test_logs_response.py | 31 +++++++++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 sdk/monitor/azure-monitor-query/tests/test_logs_response.py diff --git a/sdk/monitor/azure-monitor-query/CHANGELOG.md b/sdk/monitor/azure-monitor-query/CHANGELOG.md index 11fa24cf682f..6589176e48db 100644 --- a/sdk/monitor/azure-monitor-query/CHANGELOG.md +++ b/sdk/monitor/azure-monitor-query/CHANGELOG.md @@ -16,6 +16,7 @@ - `metric_namespace_name` is renamed to `fully_qualified_namespace` - `is_dimension_required` is renamed to `dimension_required` - `time_grain` is renamed to `granularity` +- `LogsQueryResult` now returns `datetime` objects for a time values. ### Bugs Fixed diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py index d1333a4f362c..205239d1816f 100644 --- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py +++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py @@ -6,7 +6,7 @@ # -------------------------------------------------------------------------- from datetime import datetime, timedelta from typing import TYPE_CHECKING -from msrest import Serializer +from msrest import Serializer, Deserializer from azure.core.exceptions import HttpResponseError from azure.core.pipeline.policies import BearerTokenCredentialPolicy @@ -81,3 +81,13 @@ def construct_iso8601(timespan=None): else: iso_str = duration return iso_str + +def native_col_type(col_type, value): + if col_type == 'datetime': + value = Deserializer.deserialize_iso(value) + elif col_type in ('timespan', 'guid'): + value = str(value) + return value + +def process_row(col_types, row): + return [native_col_type(col_types[ind].type, val) for ind, val in enumerate(row)] diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py index 400f9f19f04a..fcc22a6ba687 100644 --- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py +++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py @@ -9,7 +9,7 @@ import uuid from typing import Any, Optional, List -from ._helpers import construct_iso8601 +from ._helpers import construct_iso8601, process_row from ._generated.models import ( Column as InternalColumn, BatchQueryRequest as InternalLogQueryRequest, @@ -32,7 +32,7 @@ def __init__(self, name, columns, rows): # type: (str, List[LogsQueryResultColumn], List[List[str]]) -> None self.name = name self.columns = columns - self.rows = rows + self.rows = [process_row(self.columns, row) for row in rows] @classmethod def _from_generated(cls, generated): diff --git a/sdk/monitor/azure-monitor-query/tests/test_logs_response.py b/sdk/monitor/azure-monitor-query/tests/test_logs_response.py new file mode 100644 index 000000000000..3c69e01caa69 --- /dev/null +++ b/sdk/monitor/azure-monitor-query/tests/test_logs_response.py @@ -0,0 +1,31 @@ +from datetime import datetime +import pytest +import six +import os + +from azure.identity import ClientSecretCredential +from azure.monitor.query import LogsQueryClient + +def _credential(): + credential = ClientSecretCredential( + client_id = os.environ['AZURE_CLIENT_ID'], + client_secret = os.environ['AZURE_CLIENT_SECRET'], + tenant_id = os.environ['AZURE_TENANT_ID'] + ) + return credential + +@pytest.mark.live_test_only +def test_query_response_types(): + credential = _credential() + client = LogsQueryClient(credential) + query = """AppRequests | + summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId, Success, ItemCount, DurationMs""" + + # returns LogsQueryResult + result = client.query(os.environ['LOG_WORKSPACE_ID'], query, timespan=None) + assert isinstance(result.tables[0].rows[0][0], datetime) # TimeGenerated generated is a datetime + assert isinstance(result.tables[0].rows[0][1], six.string_types) # _ResourceId generated is a string + assert isinstance(result.tables[0].rows[0][2], bool) # Success generated is a bool + assert isinstance(result.tables[0].rows[0][3], int) # ItemCount generated is a int + assert isinstance(result.tables[0].rows[0][4], float) # DurationMs generated is a real +