Skip to content

Commit 3e3a397

Browse files
author
Rakshith Bhyravabhotla
authored
Get rid of LogsBatchQueryResult (Azure#20418)
* Get rid of LogsBatchQueryResult * Update sdk/monitor/azure-monitor-query/README.md * oops * comments
1 parent 0ab3cda commit 3e3a397

File tree

11 files changed

+51
-91
lines changed

11 files changed

+51
-91
lines changed

sdk/monitor/azure-monitor-query/CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
- Rename `batch_query` to `query_batch`.
1616
- Rename `LogsBatchQueryRequest` to `LogsBatchQuery`.
1717
- `include_render` is now renamed to `include_visualization` in the query API.
18-
- `LogsQueryResult` and `LogsBatchQueryResult` now return `visualization` instead of `render`.
18+
- `LogsQueryResult` now returns `visualization` instead of `render`.
1919
- `start_time`, `duration` and `end_time` are now replaced with a single param called `timespan`
2020
- `resourceregion` is renamed to `resource_region` in the MetricResult type.
2121
- `top` is renamed to `max_results` in the metric's `query` API.
@@ -30,11 +30,11 @@
3030
- `AggregationType` is renamed to `MetricAggregationType`.
3131
- Removed `LogsBatchResultError` type.
3232
- `LogsQueryResultTable` is named to `LogsTable`
33-
- `LogsQueryResultColumn` is renamed to `LogsTableColumn`
3433
- `LogsTableColumn` is now removed. Column labels are strings instead.
3534
- `start_time` in `list_metric_namespaces` API is now a datetime.
3635
- The order of params in `LogsBatchQuery` is changed. Also, `headers` is no longer accepted.
3736
- `timespan` is now a required keyword-only argument in logs APIs.
37+
- batch api now returns a list of `LogsQueryResult` objects.
3838

3939
### Bugs Fixed
4040

sdk/monitor/azure-monitor-query/README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,12 @@ for rsp in response:
215215

216216
#### Handling the response for Logs Query
217217

218-
The `query` API returns the `LogsQueryResult` while the `batch_query` API returns the `LogsBatchQueryResult`.
218+
The `query` API returns the `LogsQueryResult` while the `batch_query` API returns list of `LogsQueryResult`.
219219

220220
Here is a heirarchy of the response:
221221

222222
```
223-
LogsQueryResult / LogsBatchQueryResult
224-
|---id (this exists in `LogsBatchQueryResult` object only)
225-
|---status (this exists in `LogsBatchQueryResult` object only)
223+
LogsQueryResult
226224
|---statistics
227225
|---visualization
228226
|---error

sdk/monitor/azure-monitor-query/azure/monitor/query/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from ._models import (
1111
MetricAggregationType,
12-
LogsBatchQueryResult,
1312
LogsQueryResult,
1413
LogsTable,
1514
MetricsResult,
@@ -30,7 +29,6 @@
3029
__all__ = [
3130
"MetricAggregationType",
3231
"LogsQueryClient",
33-
"LogsBatchQueryResult",
3432
"LogsQueryResult",
3533
"LogsTable",
3634
"LogsBatchQuery",

sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@ def process_error(exception):
4545
raise_error = HttpResponseError
4646
raise raise_error(message=exception.message, response=exception.response)
4747

48-
def order_results(request_order, responses):
49-
mapping = {item.id: item for item in responses}
48+
def order_results(request_order, mapping, obj):
5049
ordered = [mapping[id] for id in request_order]
51-
return ordered
50+
return [obj._from_generated(rsp) for rsp in ordered] # pylint: disable=protected-access
5251

5352
def construct_iso8601(timespan=None):
5453
if not timespan:

sdk/monitor/azure-monitor-query/azure/monitor/query/_logs_query_client.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from ._generated.models import BatchRequest, QueryBody as LogsQueryBody
1515
from ._helpers import get_authentication_policy, process_error, construct_iso8601, order_results
16-
from ._models import LogsQueryResult, LogsBatchQuery, LogsBatchQueryResult
16+
from ._models import LogsBatchQuery, LogsQueryResult
1717

1818
if TYPE_CHECKING:
1919
from azure.core.credentials import TokenCredential
@@ -128,16 +128,16 @@ def query(self, workspace_id, query, **kwargs):
128128

129129
@distributed_trace
130130
def query_batch(self, queries, **kwargs):
131-
# type: (Union[Sequence[Dict], Sequence[LogsBatchQuery]], Any) -> List[LogsBatchQueryResult]
131+
# type: (Union[Sequence[Dict], Sequence[LogsBatchQuery]], Any) -> List[LogsQueryResult]
132132
"""Execute a list of analytics queries. Each request can be either a LogQueryRequest
133133
object or an equivalent serialized model.
134134
135135
The response is returned in the same order as that of the requests sent.
136136
137137
:param queries: The list of queries that should be processed
138138
:type queries: list[dict] or list[~azure.monitor.query.LogsBatchQuery]
139-
:return: List of LogsBatchQueryResult, or the result of cls(response)
140-
:rtype: list[~azure.monitor.query.LogsBatchQueryResult]
139+
:return: List of LogsQueryResult, or the result of cls(response)
140+
:rtype: list[~azure.monitor.query.LogsQueryResult]
141141
:raises: ~azure.core.exceptions.HttpResponseError
142142
143143
.. admonition:: Example:
@@ -160,11 +160,8 @@ def query_batch(self, queries, **kwargs):
160160
request_order = [req['id'] for req in queries]
161161
batch = BatchRequest(requests=queries)
162162
generated = self._query_op.batch(batch, **kwargs)
163-
return order_results(
164-
request_order,
165-
[
166-
LogsBatchQueryResult._from_generated(rsp) for rsp in generated.responses # pylint: disable=protected-access
167-
])
163+
mapping = {item.id: item for item in generated.responses}
164+
return order_results(request_order, mapping, LogsQueryResult)
168165

169166
def close(self):
170167
# type: () -> None

sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ._helpers import construct_iso8601, process_row
1313
from ._generated.models import (
1414
BatchQueryRequest as InternalLogQueryRequest,
15+
BatchQueryResponse
1516
)
1617

1718

@@ -47,46 +48,6 @@ def _from_generated(cls, generated):
4748
)
4849

4950

50-
class LogsQueryResult(object):
51-
"""Contains the tables, columns & rows resulting from a query.
52-
53-
:ivar tables: The list of tables, columns and rows.
54-
:vartype tables: list[~azure.monitor.query.LogsTable]
55-
:ivar statistics: This will include a statistics property in the response that describes various
56-
performance statistics such as query execution time and resource usage.
57-
:vartype statistics: object
58-
:ivar visualization: This will include a visualization property in the response that specifies the type of
59-
visualization selected by the query and any properties for that visualization.
60-
:vartype visualization: object
61-
:ivar error: Any error info.
62-
:vartype error: ~azure.core.exceptions.HttpResponseError
63-
"""
64-
def __init__(self, **kwargs):
65-
# type: (Any) -> None
66-
self.tables = kwargs.get("tables", None)
67-
self.statistics = kwargs.get("statistics", None)
68-
self.visualization = kwargs.get("visualization", None)
69-
self.error = kwargs.get("error", None)
70-
71-
@classmethod
72-
def _from_generated(cls, generated):
73-
if not generated:
74-
return cls()
75-
tables = None
76-
if generated.tables is not None:
77-
tables = [
78-
LogsTable._from_generated( # pylint: disable=protected-access
79-
table
80-
) for table in generated.tables
81-
]
82-
return cls(
83-
tables=tables,
84-
statistics=generated.statistics,
85-
visualization=generated.render,
86-
error=generated.error
87-
)
88-
89-
9051
class MetricsResult(object):
9152
"""The response to a metrics query.
9253
@@ -193,13 +154,9 @@ def _to_generated(self):
193154
workspace=self.workspace
194155
)
195156

196-
class LogsBatchQueryResult(object):
197-
"""The LogsBatchQueryResult.
157+
class LogsQueryResult(object):
158+
"""The LogsQueryResult.
198159
199-
:ivar id: the request id of the request that was sent.
200-
:vartype id: str
201-
:ivar status: status code of the response.
202-
:vartype status: int
203160
:ivar tables: The list of tables, columns and rows.
204161
:vartype tables: list[~azure.monitor.query.LogsTable]
205162
:ivar statistics: This will include a statistics property in the response that describes various
@@ -215,31 +172,30 @@ def __init__(
215172
self,
216173
**kwargs
217174
):
218-
self.id = kwargs.get('id', None)
219-
self.status = kwargs.get('status', None)
220175
self.tables = kwargs.get('tables', None)
221176
self.error = kwargs.get('error', None)
222177
self.statistics = kwargs.get('statistics', None)
223178
self.visualization = kwargs.get('visualization', None)
224179

225180
@classmethod
226181
def _from_generated(cls, generated):
182+
227183
if not generated:
228184
return cls()
229185
tables = None
230-
if generated.body.tables is not None:
186+
if isinstance(generated, BatchQueryResponse):
187+
generated = generated.body
188+
if generated.tables is not None:
231189
tables = [
232190
LogsTable._from_generated( # pylint: disable=protected-access
233191
table
234-
) for table in generated.body.tables
192+
) for table in generated.tables
235193
]
236194
return cls(
237-
id=generated.id,
238-
status=generated.status,
239195
tables=tables,
240-
statistics=generated.body.statistics,
241-
visualization=generated.body.render,
242-
error=generated.body.error
196+
statistics=generated.statistics,
197+
visualization=generated.render,
198+
error=generated.error
243199
)
244200

245201

sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_logs_query_client_async.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from .._generated.models import BatchRequest, QueryBody as LogsQueryBody
1616
from .._helpers import process_error, construct_iso8601, order_results
17-
from .._models import LogsQueryResult, LogsBatchQuery, LogsBatchQueryResult
17+
from .._models import LogsQueryResult, LogsBatchQuery
1818
from ._helpers_asyc import get_authentication_policy
1919

2020
if TYPE_CHECKING:
@@ -115,16 +115,16 @@ async def query_batch(
115115
self,
116116
queries: Union[Sequence[Dict], Sequence[LogsBatchQuery]],
117117
**kwargs: Any
118-
) -> List[LogsBatchQueryResult]:
118+
) -> List[LogsQueryResult]:
119119
"""Execute a list of analytics queries. Each request can be either a LogQueryRequest
120120
object or an equivalent serialized model.
121121
122122
The response is returned in the same order as that of the requests sent.
123123
124124
:param queries: The list of queries that should be processed
125125
:type queries: list[dict] or list[~azure.monitor.query.LogsBatchQuery]
126-
:return: list of LogsBatchQueryResult objects, or the result of cls(response)
127-
:rtype: list[~azure.monitor.query.LogsBatchQueryResult]
126+
:return: list of LogsQueryResult objects, or the result of cls(response)
127+
:rtype: list[~azure.monitor.query.LogsQueryResult]
128128
:raises: ~azure.core.exceptions.HttpResponseError
129129
"""
130130
try:
@@ -138,11 +138,8 @@ async def query_batch(
138138
request_order = [req['id'] for req in queries]
139139
batch = BatchRequest(requests=queries)
140140
generated = await self._query_op.batch(batch, **kwargs)
141-
return order_results(
142-
request_order,
143-
[
144-
LogsBatchQueryResult._from_generated(rsp) for rsp in generated.responses # pylint: disable=protected-access
145-
])
141+
mapping = {item.id: item for item in generated.responses}
142+
return order_results(request_order, mapping, LogsQueryResult)
146143

147144
async def __aenter__(self) -> "LogsQueryClient":
148145
await self._client.__aenter__()

sdk/monitor/azure-monitor-query/samples/sample_batch_query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
for response in responses:
3838
try:
3939
table = response.tables[0]
40-
df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns])
40+
df = pd.DataFrame(table.rows, columns=table.columns)
4141
print(df)
4242
print("\n\n-------------------------\n\n")
4343
except TypeError:

sdk/monitor/azure-monitor-query/tests/async/test_logs_client_async.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ async def test_logs_query_batch_raises_on_no_timespan():
6969

7070
@pytest.mark.live_test_only
7171
@pytest.mark.asyncio
72-
async def test_logs_query_batch():
72+
async def test_logs_query_batch_default():
7373
client = LogsQueryClient(_credential())
7474

7575
requests = [
@@ -85,14 +85,22 @@ async def test_logs_query_batch():
8585
workspace_id= os.environ['LOG_WORKSPACE_ID']
8686
),
8787
LogsBatchQuery(
88-
query= "AppRequests | take 2",
88+
query= "Wrong query | take 2",
8989
workspace_id= os.environ['LOG_WORKSPACE_ID'],
9090
timespan=None
9191
),
9292
]
9393
response = await client.query_batch(requests)
9494

9595
assert len(response) == 3
96+
r0 = response[0]
97+
assert r0.tables[0].columns == ['count_']
98+
r1 = response[1]
99+
assert r1.tables[0].columns[0] == 'TimeGenerated'
100+
assert r1.tables[0].columns[1] == '_ResourceId'
101+
assert r1.tables[0].columns[2] == 'avgRequestDuration'
102+
r2 = response[2]
103+
assert r2.error is not None
96104

97105
@pytest.mark.skip('https://github.com/Azure/azure-sdk-for-python/issues/19382')
98106
@pytest.mark.live_test_only

sdk/monitor/azure-monitor-query/tests/test_logs_client.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def test_logs_server_timeout():
7676
assert 'Gateway timeout' in e.value.message
7777

7878
@pytest.mark.live_test_only
79-
def test_logs_query_batch():
79+
def test_logs_query_batch_default():
8080
client = LogsQueryClient(_credential())
8181

8282
requests = [
@@ -92,14 +92,23 @@ def test_logs_query_batch():
9292
workspace_id= os.environ['LOG_WORKSPACE_ID']
9393
),
9494
LogsBatchQuery(
95-
query= "AppRequests | take 2",
95+
query= "Wrong query | take 2",
9696
workspace_id= os.environ['LOG_WORKSPACE_ID'],
9797
timespan=None
9898
),
9999
]
100100
response = client.query_batch(requests)
101101

102102
assert len(response) == 3
103+
104+
r0 = response[0]
105+
assert r0.tables[0].columns == ['count_']
106+
r1 = response[1]
107+
assert r1.tables[0].columns[0] == 'TimeGenerated'
108+
assert r1.tables[0].columns[1] == '_ResourceId'
109+
assert r1.tables[0].columns[2] == 'avgRequestDuration'
110+
r2 = response[2]
111+
assert r2.error is not None
103112

104113
@pytest.mark.live_test_only
105114
def test_logs_single_query_with_statistics():

0 commit comments

Comments
 (0)