diff --git a/.apigentools-info b/.apigentools-info index ad3d5c414f..18165c78d8 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.5", - "regenerated": "2023-08-30 07:29:22.537461", - "spec_repo_commit": "febdee32" + "regenerated": "2023-08-30 08:42:52.326487", + "spec_repo_commit": "fee86b40" }, "v2": { "apigentools_version": "1.6.5", - "regenerated": "2023-08-30 07:29:22.557428", - "spec_repo_commit": "febdee32" + "regenerated": "2023-08-30 08:42:52.374431", + "spec_repo_commit": "fee86b40" } } } \ No newline at end of file diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index 815826382e..3ed657399e 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -24896,6 +24896,7 @@ paths: name: page_size required: false schema: + default: 100 example: 20 format: int32 maximum: 1000 @@ -24931,6 +24932,9 @@ paths: summary: Get all monitor details tags: - Monitors + x-pagination: + limitParam: page_size + pageParam: page post: description: 'Create a monitor using the specified options. diff --git a/examples/v1/monitors/ListMonitors_2966492814.py b/examples/v1/monitors/ListMonitors_2966492814.py new file mode 100644 index 0000000000..2be8ffa729 --- /dev/null +++ b/examples/v1/monitors/ListMonitors_2966492814.py @@ -0,0 +1,15 @@ +""" +Get all monitor details returns "OK" response with pagination +""" + +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v1.api.monitors_api import MonitorsApi + +configuration = Configuration() +with ApiClient(configuration) as api_client: + api_instance = MonitorsApi(api_client) + items = api_instance.list_monitors_with_pagination( + page_size=2, + ) + for item in items: + print(item) diff --git a/src/datadog_api_client/api_client.py b/src/datadog_api_client/api_client.py index 884e6eb05d..78e17e3e50 100644 --- a/src/datadog_api_client/api_client.py +++ b/src/datadog_api_client/api_client.py @@ -346,6 +346,13 @@ def call_api_paginated( host: Optional[str] = None, check_type: Optional[bool] = None, ): + if "page_param" in pagination: + set_attribute_from_path( + pagination["kwargs"], + pagination["page_param"], + 0, + pagination["endpoint"].params_map, + ) params = pagination["endpoint"].gather_params(pagination["kwargs"]) while True: response = self.call_api( @@ -365,9 +372,9 @@ def call_api_paginated( host=host, collection_formats=params["collection_format"], ) - for item in get_attribute_from_path(response, pagination["results_path"]): + for item in get_attribute_from_path(response, pagination.get("results_path")): yield item - if len(get_attribute_from_path(response, pagination["results_path"])) < pagination["limit_value"]: + if len(get_attribute_from_path(response, pagination.get("results_path"))) < pagination["limit_value"]: break params = self._update_paginated_params(pagination, response) @@ -381,6 +388,13 @@ def _update_paginated_params(self, pagination, response): + pagination["limit_value"], pagination["endpoint"].params_map, ) + elif "page_param" in pagination: + set_attribute_from_path( + pagination["kwargs"], + pagination["page_param"], + get_attribute_from_path(pagination["kwargs"], pagination["page_param"], 0) + 1, + pagination["endpoint"].params_map, + ) else: set_attribute_from_path( pagination["kwargs"], @@ -633,9 +647,9 @@ async def call_api_paginated( host=host, collection_formats=params["collection_format"], ) - for item in get_attribute_from_path(response, pagination["results_path"]): + for item in get_attribute_from_path(response, pagination.get("results_path")): yield item - if len(get_attribute_from_path(response, pagination["results_path"])) < pagination["limit_value"]: + if len(get_attribute_from_path(response, pagination.get("results_path"))) < pagination["limit_value"]: break params = self._update_paginated_params(pagination, response) diff --git a/src/datadog_api_client/model_utils.py b/src/datadog_api_client/model_utils.py index 19df4f0e30..9c1c4e22a8 100644 --- a/src/datadog_api_client/model_utils.py +++ b/src/datadog_api_client/model_utils.py @@ -1639,6 +1639,8 @@ def __init__(self, **kwargs): def get_attribute_from_path(obj, path, default=None): """Return an attribute at `path` from the passed object.""" + if not path: + return obj for elt in path.split("."): try: obj = obj[elt] diff --git a/src/datadog_api_client/v1/api/monitors_api.py b/src/datadog_api_client/v1/api/monitors_api.py index 4657461db8..717bbf7e8b 100644 --- a/src/datadog_api_client/v1/api/monitors_api.py +++ b/src/datadog_api_client/v1/api/monitors_api.py @@ -3,11 +3,14 @@ # Copyright 2019-Present Datadog, Inc. from __future__ import annotations +import collections from typing import Any, Dict, List, Union from datadog_api_client.api_client import ApiClient, Endpoint as _Endpoint from datadog_api_client.configuration import Configuration from datadog_api_client.model_utils import ( + set_attribute_from_path, + get_attribute_from_path, UnsetType, unset, ) @@ -693,6 +696,81 @@ def list_monitors( return self._list_monitors_endpoint.call_with_http_info(**kwargs) + def list_monitors_with_pagination( + self, + *, + group_states: Union[str, UnsetType] = unset, + name: Union[str, UnsetType] = unset, + tags: Union[str, UnsetType] = unset, + monitor_tags: Union[str, UnsetType] = unset, + with_downtimes: Union[bool, UnsetType] = unset, + id_offset: Union[int, UnsetType] = unset, + page: Union[int, UnsetType] = unset, + page_size: Union[int, UnsetType] = unset, + ) -> collections.abc.Iterable[Monitor]: + """Get all monitor details. + + Provide a paginated version of :meth:`list_monitors`, returning all items. + + :param group_states: When specified, shows additional information about the group states. + Choose one or more from ``all`` , ``alert`` , ``warn`` , and ``no data``. + :type group_states: str, optional + :param name: A string to filter monitors by name. + :type name: str, optional + :param tags: A comma separated list indicating what tags, if any, should be used to filter the list of monitors by scope. + For example, ``host:host0``. + :type tags: str, optional + :param monitor_tags: A comma separated list indicating what service and/or custom tags, if any, should be used to filter the list of monitors. + Tags created in the Datadog UI automatically have the service key prepended. For example, ``service:my-app``. + :type monitor_tags: str, optional + :param with_downtimes: If this argument is set to true, then the returned data includes all current active downtimes for each monitor. + :type with_downtimes: bool, optional + :param id_offset: Use this parameter for paginating through large sets of monitors. Start with a value of zero, make a request, set the value to the last ID of result set, and then repeat until the response is empty. + :type id_offset: int, optional + :param page: The page to start paginating from. If this argument is not specified, the request returns all monitors without pagination. + :type page: int, optional + :param page_size: The number of monitors to return per page. If the page argument is not specified, the default behavior returns all monitors without a ``page_size`` limit. However, if page is specified and ``page_size`` is not, the argument defaults to 100. + :type page_size: int, optional + + :return: A generator of paginated results. + :rtype: collections.abc.Iterable[Monitor] + """ + kwargs: Dict[str, Any] = {} + if group_states is not unset: + kwargs["group_states"] = group_states + + if name is not unset: + kwargs["name"] = name + + if tags is not unset: + kwargs["tags"] = tags + + if monitor_tags is not unset: + kwargs["monitor_tags"] = monitor_tags + + if with_downtimes is not unset: + kwargs["with_downtimes"] = with_downtimes + + if id_offset is not unset: + kwargs["id_offset"] = id_offset + + if page is not unset: + kwargs["page"] = page + + if page_size is not unset: + kwargs["page_size"] = page_size + + local_page_size = get_attribute_from_path(kwargs, "page_size", 100) + endpoint = self._list_monitors_endpoint + set_attribute_from_path(kwargs, "page_size", local_page_size, endpoint.params_map) + pagination = { + "limit_value": local_page_size, + "page_param": "page", + "endpoint": endpoint, + "kwargs": kwargs, + } + return endpoint.call_with_http_info_paginated(pagination) + def search_monitor_groups( self, *, diff --git a/tests/v1/cassettes/test_scenarios/test_get_all_monitor_details_returns_ok_response_with_pagination.frozen b/tests/v1/cassettes/test_scenarios/test_get_all_monitor_details_returns_ok_response_with_pagination.frozen new file mode 100644 index 0000000000..7cbbf8aaca --- /dev/null +++ b/tests/v1/cassettes/test_scenarios/test_get_all_monitor_details_returns_ok_response_with_pagination.frozen @@ -0,0 +1 @@ +2023-08-28T07:51:42.436Z \ No newline at end of file diff --git a/tests/v1/cassettes/test_scenarios/test_get_all_monitor_details_returns_ok_response_with_pagination.yaml b/tests/v1/cassettes/test_scenarios/test_get_all_monitor_details_returns_ok_response_with_pagination.yaml new file mode 100644 index 0000000000..6803047ef2 --- /dev/null +++ b/tests/v1/cassettes/test_scenarios/test_get_all_monitor_details_returns_ok_response_with_pagination.yaml @@ -0,0 +1,50 @@ +interactions: +- request: + body: null + headers: + accept: + - application/json + method: GET + uri: https://api.datadoghq.com/api/v1/monitor?page_size=2&page=0 + response: + body: + string: '[{"id":34822915,"org_id":321813,"type":"query alert","name":"SLO Monitor: + aws_alb_latency_p95 for splunk","message":"Latency SLO violation for splunk + load balancer(s)","tags":["environment:test","generator:slops","release:e6a2686","sli:latency","slotype:alb","systemid:splunk","team:developer_insights"],"query":"avg(last_1m):avg:aws.applicationelb.target_response_time.p95{systemid:splunk,aws_account_type:production} + by {region} > 0.2","options":{"notify_audit":false,"locked":false,"include_tags":true,"thresholds":{"critical":0.2},"new_host_delay":300,"require_full_window":true,"notify_no_data":false,"silenced":{}},"multi":true,"created_at":1620047024000,"created":"2021-05-03T13:03:44.905085+00:00","modified":"2021-05-03T13:03:44.905085+00:00","deleted":null,"restricted_roles":null,"priority":null,"overall_state_modified":"2021-05-03T13:06:23+00:00","overall_state":"No + Data","creator":{"name":null,"handle":"frog@datadoghq.com","email":"frog@datadoghq.com","id":1445416},"matching_downtimes":[]},{"id":34822916,"org_id":321813,"type":"query + alert","name":"SLO Monitor: aws_classic_elb_latency_p99 for splunk","message":"Latency + SLO violation for splunk load balancer(s)","tags":["environment:test","generator:slops","release:e6a2686","sli:latency","slotype:elb","systemid:splunk","team:developer_insights"],"query":"avg(last_1m):avg:aws.elb.latency.p99{systemid:splunk,aws_account_type:production} + by {region} > 0.2","options":{"notify_audit":false,"locked":false,"include_tags":true,"thresholds":{"critical":0.2},"new_host_delay":300,"require_full_window":true,"notify_no_data":false,"silenced":{}},"multi":true,"created_at":1620047024000,"created":"2021-05-03T13:03:44.909928+00:00","modified":"2021-05-03T13:03:44.909928+00:00","deleted":null,"restricted_roles":null,"priority":null,"overall_state_modified":"2021-05-03T13:06:18+00:00","overall_state":"No + Data","creator":{"name":null,"handle":"frog@datadoghq.com","email":"frog@datadoghq.com","id":1445416},"matching_downtimes":[]}] + + ' + headers: + content-type: + - application/json + status: + code: 200 + message: OK +- request: + body: null + headers: + accept: + - application/json + method: GET + uri: https://api.datadoghq.com/api/v1/monitor?page_size=2&page=1 + response: + body: + string: '[{"id":34822917,"org_id":321813,"type":"query alert","name":"SLO Monitor: + aws_alb_latency_p50 for splunk","message":"Latency SLO violation for splunk + load balancer(s)","tags":["environment:test","generator:slops","release:e6a2686","sli:latency","slotype:alb","systemid:splunk","team:developer_insights"],"query":"avg(last_1m):avg:aws.applicationelb.target_response_time.p50{systemid:splunk,aws_account_type:production} + by {region} > 0.2","options":{"notify_audit":false,"locked":false,"include_tags":true,"thresholds":{"critical":0.2},"new_host_delay":300,"require_full_window":true,"notify_no_data":false,"silenced":{}},"multi":true,"created_at":1620047024000,"created":"2021-05-03T13:03:44.920644+00:00","modified":"2021-05-03T13:03:44.920644+00:00","deleted":null,"restricted_roles":null,"priority":null,"overall_state_modified":"2021-05-03T13:06:37+00:00","overall_state":"No + Data","creator":{"name":null,"handle":"frog@datadoghq.com","email":"frog@datadoghq.com","id":1445416},"matching_downtimes":[]}] + + ' + headers: + content-type: + - application/json + status: + code: 200 + message: OK +version: 1 diff --git a/tests/v1/features/monitors.feature b/tests/v1/features/monitors.feature index 0fa7ba6a40..e8f59cfbb5 100644 --- a/tests/v1/features/monitors.feature +++ b/tests/v1/features/monitors.feature @@ -227,6 +227,14 @@ Feature: Monitors When the request is sent Then the response status is 200 OK + @replay-only @skip-validation @team:DataDog/monitor-app @with-pagination + Scenario: Get all monitor details returns "OK" response with pagination + Given new "ListMonitors" request + And request contains "page_size" parameter with value 2 + When the request with pagination is sent + Then the response status is 200 OK + And the response has 3 items + @skip @team:DataDog/monitor-app Scenario: Get all monitor details with tags Given there is a valid "monitor" in the system