From 4279c9252c21e24a43d2613de7fdb1af35dc30fc Mon Sep 17 00:00:00 2001 From: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> Date: Thu, 18 Feb 2021 09:22:02 -0700 Subject: [PATCH] fix: allow any set query_params to work with `query.iter()` (#83) Construct a `ListTimeSeriesRequest` from the query params rather than passing them directly to the function. This is important when one of the params is "optional" and is not available as a kwarg on the `list_time_series()` method. For example, `aggregation` must be set on the request object. Fixes #80 ```py def list_time_series( self, request: metric_service.ListTimeSeriesRequest = None, *, name: str = None, filter: str = None, interval: common.TimeInterval = None, view: metric_service.ListTimeSeriesRequest.TimeSeriesView = None, retry: retries.Retry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListTimeSeriesPager: ``` ```py class ListTimeSeriesRequest(proto.Message): r"""The ``ListTimeSeries`` request. Attributes: name (str): Required. The project on which to execute the request. The format is: :: projects/[PROJECT_ID_OR_NUMBER] filter (str): Required. A `monitoring filter `__ that specifies which time series should be returned. The filter must specify a single metric type, and can additionally specify metric labels and other information. For example: :: metric.type = "compute.googleapis.com/instance/cpu/usage_time" AND metric.labels.instance_name = "my-instance-name". interval (~.common.TimeInterval): Required. The time interval for which results should be returned. Only time series that contain data points in the specified interval are included in the response. aggregation (~.common.Aggregation): Specifies the alignment of data points in individual time series as well as how to combine the retrieved time series across specified labels. By default (if no ``aggregation`` is explicitly specified), the raw time series data is returned. order_by (str): Unsupported: must be left blank. The points in each time series are currently returned in reverse time order (most recent to oldest). view (~.metric_service.ListTimeSeriesRequest.TimeSeriesView): Required. Specifies which information is returned about the time series. page_size (int): A positive number that is the maximum number of results to return. If ``page_size`` is empty or more than 100,000 results, the effective ``page_size`` is 100,000 results. If ``view`` is set to ``FULL``, this is the maximum number of ``Points`` returned. If ``view`` is set to ``HEADERS``, this is the maximum number of ``TimeSeries`` returned. page_token (str): If this field is not empty then it must contain the ``nextPageToken`` value returned by a previous call to this method. Using this field causes the method to return additional results from the previous method call. """ ``` --- google/cloud/monitoring_v3/query.py | 4 +++- tests/unit/test_query.py | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/google/cloud/monitoring_v3/query.py b/google/cloud/monitoring_v3/query.py index 95f80848..34cee9c2 100644 --- a/google/cloud/monitoring_v3/query.py +++ b/google/cloud/monitoring_v3/query.py @@ -443,7 +443,9 @@ def iter(self, headers_only=False, page_size=None): raise ValueError("Query time interval not specified.") params = self._build_query_params(headers_only, page_size) - for ts in self._client.list_time_series(**params): + + request = monitoring_v3.ListTimeSeriesRequest(**params) + for ts in self._client.list_time_series(request): yield ts def _build_query_params(self, headers_only=False, page_size=None): diff --git a/tests/unit/test_query.py b/tests/unit/test_query.py index 23b47193..cf835e90 100644 --- a/tests/unit/test_query.py +++ b/tests/unit/test_query.py @@ -394,6 +394,10 @@ def test_iteration_headers_only(self): client = self._create_client(channel) query = self._make_one(client, PROJECT, METRIC_TYPE) query = query.select_interval(start_time=T0, end_time=T1) + + # add a temporal alignment to test that "aggregation" query params is + # correctly processed + query = query.align(monitoring_v3.Aggregation.Aligner.ALIGN_MAX, seconds=3600) response = list(query.iter(headers_only=True)) self.assertEqual(len(response), 2) @@ -412,6 +416,10 @@ def test_iteration_headers_only(self): filter='metric.type = "{type}"'.format(type=METRIC_TYPE), interval=self._make_interval(T1, T0), view=monitoring_v3.ListTimeSeriesRequest.TimeSeriesView.HEADERS, + aggregation=monitoring_v3.Aggregation( + per_series_aligner=monitoring_v3.Aggregation.Aligner.ALIGN_MAX, + alignment_period={"seconds": 3600}, + ), ) request = channel.requests[0][1] self.assertEqual(request, expected_request)