diff --git a/generated/docs/ActionsApi.md b/generated/docs/ActionsApi.md index f1d5b017..306424fb 100644 --- a/generated/docs/ActionsApi.md +++ b/generated/docs/ActionsApi.md @@ -296,6 +296,8 @@ with groundlight_openapi_client.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = actions_api.ActionsApi(api_client) detector_id = "detector_id_example" # str | + page = 1 # int | A page number within the paginated result set. (optional) + page_size = 1 # int | Number of results to return per page. (optional) # example passing only required values which don't have defaults set try: @@ -303,6 +305,14 @@ with groundlight_openapi_client.ApiClient(configuration) as api_client: pprint(api_response) except groundlight_openapi_client.ApiException as e: print("Exception when calling ActionsApi->list_detector_rules: %s\n" % e) + + # example passing only required values which don't have defaults set + # and optional values + try: + api_response = api_instance.list_detector_rules(detector_id, page=page, page_size=page_size) + pprint(api_response) + except groundlight_openapi_client.ApiException as e: + print("Exception when calling ActionsApi->list_detector_rules: %s\n" % e) ``` @@ -311,6 +321,8 @@ with groundlight_openapi_client.ApiClient(configuration) as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **detector_id** | **str**| | + **page** | **int**| A page number within the paginated result set. | [optional] + **page_size** | **int**| Number of results to return per page. | [optional] ### Return type diff --git a/generated/docs/ImageQueriesApi.md b/generated/docs/ImageQueriesApi.md index 3d405374..e3f91416 100644 --- a/generated/docs/ImageQueriesApi.md +++ b/generated/docs/ImageQueriesApi.md @@ -201,14 +201,14 @@ configuration.api_key['ApiToken'] = 'YOUR_API_KEY' with groundlight_openapi_client.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = image_queries_api.ImageQueriesApi(api_client) + detector_id = "detector_id_example" # str | Optionally filter image queries by detector ID. (optional) page = 1 # int | A page number within the paginated result set. (optional) page_size = 1 # int | Number of items to return per page. (optional) - detector_id = "detector_id_example" # str | Optionally filter image queries by detector ID. (optional) # example passing only required values which don't have defaults set # and optional values try: - api_response = api_instance.list_image_queries(page=page, page_size=page_size, detector_id=detector_id) + api_response = api_instance.list_image_queries(detector_id=detector_id, page=page, page_size=page_size) pprint(api_response) except groundlight_openapi_client.ApiException as e: print("Exception when calling ImageQueriesApi->list_image_queries: %s\n" % e) @@ -219,9 +219,9 @@ with groundlight_openapi_client.ApiClient(configuration) as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + **detector_id** | **str**| Optionally filter image queries by detector ID. | [optional] **page** | **int**| A page number within the paginated result set. | [optional] **page_size** | **int**| Number of items to return per page. | [optional] - **detector_id** | **str**| Optionally filter image queries by detector ID. | [optional] ### Return type diff --git a/generated/groundlight_openapi_client/api/actions_api.py b/generated/groundlight_openapi_client/api/actions_api.py index 47ac8d0d..4f9d42f5 100644 --- a/generated/groundlight_openapi_client/api/actions_api.py +++ b/generated/groundlight_openapi_client/api/actions_api.py @@ -173,6 +173,8 @@ def __init__(self, api_client=None): params_map={ "all": [ "detector_id", + "page", + "page_size", ], "required": [ "detector_id", @@ -186,12 +188,18 @@ def __init__(self, api_client=None): "allowed_values": {}, "openapi_types": { "detector_id": (str,), + "page": (int,), + "page_size": (int,), }, "attribute_map": { "detector_id": "detector_id", + "page": "page", + "page_size": "page_size", }, "location_map": { "detector_id": "path", + "page": "query", + "page_size": "query", }, "collection_format_map": {}, }, @@ -434,6 +442,8 @@ def list_detector_rules(self, detector_id, **kwargs): detector_id (str): Keyword Args: + page (int): A page number within the paginated result set.. [optional] + page_size (int): Number of results to return per page.. [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object diff --git a/generated/groundlight_openapi_client/api/image_queries_api.py b/generated/groundlight_openapi_client/api/image_queries_api.py index 906bb202..03ad2600 100644 --- a/generated/groundlight_openapi_client/api/image_queries_api.py +++ b/generated/groundlight_openapi_client/api/image_queries_api.py @@ -127,9 +127,9 @@ def __init__(self, api_client=None): }, params_map={ "all": [ + "detector_id", "page", "page_size", - "detector_id", ], "required": [], "nullable": [], @@ -140,19 +140,19 @@ def __init__(self, api_client=None): "validations": {}, "allowed_values": {}, "openapi_types": { + "detector_id": (str,), "page": (int,), "page_size": (int,), - "detector_id": (str,), }, "attribute_map": { + "detector_id": "detector_id", "page": "page", "page_size": "page_size", - "detector_id": "detector_id", }, "location_map": { + "detector_id": "query", "page": "query", "page_size": "query", - "detector_id": "query", }, "collection_format_map": {}, }, @@ -377,9 +377,9 @@ def list_image_queries(self, **kwargs): Keyword Args: + detector_id (str): Optionally filter image queries by detector ID.. [optional] page (int): A page number within the paginated result set.. [optional] page_size (int): Number of items to return per page.. [optional] - detector_id (str): Optionally filter image queries by detector ID.. [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object diff --git a/generated/model.py b/generated/model.py index b8f4da4a..0461d864 100644 --- a/generated/model.py +++ b/generated/model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: public-api.yaml -# timestamp: 2024-12-13T20:10:31+00:00 +# timestamp: 2024-12-19T23:20:30+00:00 from __future__ import annotations diff --git a/spec/public-api.yaml b/spec/public-api.yaml index 10e8ecaa..d5f49198 100644 --- a/spec/public-api.yaml +++ b/spec/public-api.yaml @@ -19,6 +19,18 @@ paths: schema: type: string required: true + - name: page + required: false + in: query + description: A page number within the paginated result set. + schema: + type: integer + - name: page_size + required: false + in: query + description: Number of results to return per page. + schema: + type: integer tags: - actions security: diff --git a/src/groundlight/experimental_api.py b/src/groundlight/experimental_api.py index 5b8765b8..ee8d6ed7 100644 --- a/src/groundlight/experimental_api.py +++ b/src/groundlight/experimental_api.py @@ -214,6 +214,33 @@ def get_rule(self, action_id: int) -> Rule: """ return Rule.model_validate(self.actions_api.get_rule(action_id).to_dict()) + def list_detector_rules(self, detector: Union[str, Detector], page=1, page_size=10) -> PaginatedRuleList: + """ + Gets a paginated list of rules associated with the given detector. + + **Example usage**:: + + gl = ExperimentalApi() + + # Get all rules for a specific detector + rules = gl.list_detector_rules(det_mydetectorid) + for rule in rules.results: + print(f"Rule {rule.id}: {rule.name}") + + # Get next page + next_page = gl.list_detector_rules(det_mydetectorid, page=2) + + :param detector: the detector or detector_id to get the rules for + :param page: the page number to retrieve (default: 1) + :param page_size: the number of rules per page (default: 10) + :return: a list of Rule objects associated with the given detector + """ + if isinstance(detector, Detector): + detector = detector.id + return PaginatedRuleList.parse_obj( + self.actions_api.list_detector_rules(detector, page=page, page_size=page_size).to_dict() + ) + def delete_rule(self, action_id: int) -> None: """ Deletes the rule with the given id. @@ -255,13 +282,11 @@ def list_rules(self, page=1, page_size=10) -> PaginatedRuleList: obj = self.actions_api.list_rules(page=page, page_size=page_size) return PaginatedRuleList.parse_obj(obj.to_dict()) - def delete_all_rules(self, detector: Union[None, str, Detector] = None) -> int: + def delete_all_rules(self, detector: Union[str, Detector]) -> int: """ - Deletes all rules associated with the given detector. If no detector is specified, - deletes all rules in the account. + Deletes all rules associated with the given detector. - WARNING: If no detector is specified, this will delete ALL rules in your account. - This action cannot be undone. Use with caution. + WARNING: This action cannot be undone. Use with caution. **Example usage**:: @@ -272,11 +297,7 @@ def delete_all_rules(self, detector: Union[None, str, Detector] = None) -> int: num_deleted = gl.delete_all_rules(detector) print(f"Deleted {num_deleted} rules") - # Delete all rules in the account - num_deleted = gl.delete_all_rules() - print(f"Deleted {num_deleted} rules") - - :param detector: the detector to delete the rules from. If None, deletes all rules. + :param detector: the detector to delete the rules from. :return: the number of rules deleted """ @@ -286,9 +307,7 @@ def delete_all_rules(self, detector: Union[None, str, Detector] = None) -> int: num_rules = self.list_rules().count for page in range(1, (num_rules // self.ITEMS_PER_PAGE) + 2): for rule in self.list_rules(page=page, page_size=self.ITEMS_PER_PAGE).results: - if det_id is None: - ids_to_delete.append(rule.id) - elif rule.detector_id == det_id: + if rule.detector_id == det_id: ids_to_delete.append(rule.id) for rule_id in ids_to_delete: self.delete_rule(rule_id) diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index d620255b..6f014b46 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -6,8 +6,6 @@ def test_create_action(gl_experimental: ExperimentalApi): - # We first clear out any rules in case the account has any left over from a previous test - gl_experimental.delete_all_rules() name = f"Test {datetime.utcnow()}" det = gl_experimental.get_or_create_detector(name, "test_query") rule = gl_experimental.create_rule(det, f"test_rule_{name}", "EMAIL", "test@example.com") @@ -15,22 +13,30 @@ def test_create_action(gl_experimental: ExperimentalApi): assert rule == rule2 -@pytest.mark.skip(reason="actions are global on account, the test matrix collides with itself") # type: ignore def test_get_all_actions(gl_experimental: ExperimentalApi): name = f"Test {datetime.utcnow()}" num_test_rules = 13 # needs to be larger than the default page size gl_experimental.ITEMS_PER_PAGE = 10 assert gl_experimental.ITEMS_PER_PAGE < num_test_rules det = gl_experimental.get_or_create_detector(name, "test_query") - gl_experimental.delete_all_rules() for i in range(num_test_rules): _ = gl_experimental.create_rule(det, f"test_rule_{i}", "EMAIL", "test@example.com") rules = gl_experimental.list_rules(page_size=gl_experimental.ITEMS_PER_PAGE) - assert rules.count == num_test_rules + # The exact number of actions is not guaranteed if another client is making calls at the same time + assert rules.count > num_test_rules assert len(rules.results) == gl_experimental.ITEMS_PER_PAGE - num_deleted = gl_experimental.delete_all_rules() - assert num_deleted == num_test_rules - rules = gl_experimental.list_rules() + + +def test_delete_actions(gl_experimental: ExperimentalApi): + name = f"Test {datetime.utcnow()}" + num_test_rules = 13 # needs to be larger than the default page size + det = gl_experimental.get_or_create_detector(name, "test_query") + for i in range(num_test_rules): + _ = gl_experimental.create_rule(det, f"test_rule_{i}", "EMAIL", "test@example.com") + rules = gl_experimental.list_detector_rules(det.id) + assert rules.count == num_test_rules + gl_experimental.delete_all_rules(det.id) + rules = gl_experimental.list_detector_rules(det.id) assert rules.count == 0