From 5534295c1237cb67fd5451f10b179c67b317b2a2 Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Wed, 12 Feb 2025 00:04:40 +0000 Subject: [PATCH 01/12] regenerate --- generated/.openapi-generator/FILES | 10 +- generated/README.md | 5 +- generated/docs/ActionsApi.md | 1 + generated/docs/Detector.md | 2 +- generated/docs/ImageQuery.md | 2 +- generated/docs/PatchedDetectorRequest.md | 2 +- generated/docs/PayloadTemplate.md | 12 + generated/docs/PayloadTemplateRequest.md | 12 + generated/docs/WebhookAction.md | 1 + generated/docs/WebhookActionRequest.md | 1 + .../apis/__init__.py | 1 - .../model/payload_template.py | 274 +++++++++++++++++ .../model/payload_template_request.py | 278 ++++++++++++++++++ .../model/webhook_action.py | 22 ++ .../model/webhook_action_request.py | 22 ++ .../models/__init__.py | 3 +- generated/model.py | 40 +-- generated/test/test_payload_template.py | 35 +++ .../test/test_payload_template_request.py | 35 +++ spec/public-api.yaml | 78 ++--- 20 files changed, 747 insertions(+), 89 deletions(-) create mode 100644 generated/docs/PayloadTemplate.md create mode 100644 generated/docs/PayloadTemplateRequest.md create mode 100644 generated/groundlight_openapi_client/model/payload_template.py create mode 100644 generated/groundlight_openapi_client/model/payload_template_request.py create mode 100644 generated/test/test_payload_template.py create mode 100644 generated/test/test_payload_template_request.py diff --git a/generated/.openapi-generator/FILES b/generated/.openapi-generator/FILES index 5b99bab8..a9c92fcf 100644 --- a/generated/.openapi-generator/FILES +++ b/generated/.openapi-generator/FILES @@ -22,8 +22,6 @@ docs/DetectorGroupsApi.md docs/DetectorResetApi.md docs/DetectorTypeEnum.md docs/DetectorsApi.md -docs/EdgeApi.md -docs/EdgeModelInfo.md docs/EscalationTypeEnum.md docs/ImageQueriesApi.md docs/ImageQuery.md @@ -42,6 +40,8 @@ docs/PaginatedDetectorList.md docs/PaginatedImageQueryList.md docs/PaginatedRuleList.md docs/PatchedDetectorRequest.md +docs/PayloadTemplate.md +docs/PayloadTemplateRequest.md docs/ROI.md docs/ROIRequest.md docs/ResultTypeEnum.md @@ -62,7 +62,6 @@ groundlight_openapi_client/api/actions_api.py groundlight_openapi_client/api/detector_groups_api.py groundlight_openapi_client/api/detector_reset_api.py groundlight_openapi_client/api/detectors_api.py -groundlight_openapi_client/api/edge_api.py groundlight_openapi_client/api/image_queries_api.py groundlight_openapi_client/api/labels_api.py groundlight_openapi_client/api/notes_api.py @@ -90,7 +89,6 @@ groundlight_openapi_client/model/detector_creation_input_request.py groundlight_openapi_client/model/detector_group.py groundlight_openapi_client/model/detector_group_request.py groundlight_openapi_client/model/detector_type_enum.py -groundlight_openapi_client/model/edge_model_info.py groundlight_openapi_client/model/escalation_type_enum.py groundlight_openapi_client/model/image_query.py groundlight_openapi_client/model/image_query_type_enum.py @@ -106,6 +104,8 @@ groundlight_openapi_client/model/paginated_detector_list.py groundlight_openapi_client/model/paginated_image_query_list.py groundlight_openapi_client/model/paginated_rule_list.py groundlight_openapi_client/model/patched_detector_request.py +groundlight_openapi_client/model/payload_template.py +groundlight_openapi_client/model/payload_template_request.py groundlight_openapi_client/model/result_type_enum.py groundlight_openapi_client/model/roi.py groundlight_openapi_client/model/roi_request.py @@ -126,4 +126,6 @@ setup.cfg setup.py test-requirements.txt test/__init__.py +test/test_payload_template.py +test/test_payload_template_request.py tox.ini diff --git a/generated/README.md b/generated/README.md index accfe08f..28f94663 100644 --- a/generated/README.md +++ b/generated/README.md @@ -94,6 +94,7 @@ rule_request = RuleRequest( WebhookActionRequest( url="url_example", include_image=True, + payload_template=None, ), ], ) # RuleRequest | @@ -124,7 +125,6 @@ Class | Method | HTTP request | Description *DetectorsApi* | [**get_detector**](docs/DetectorsApi.md#get_detector) | **GET** /v1/detectors/{id} | *DetectorsApi* | [**list_detectors**](docs/DetectorsApi.md#list_detectors) | **GET** /v1/detectors | *DetectorsApi* | [**update_detector**](docs/DetectorsApi.md#update_detector) | **PATCH** /v1/detectors/{id} | -*EdgeApi* | [**get_model_urls**](docs/EdgeApi.md#get_model_urls) | **GET** /v1/edge/fetch-model-urls/{detector_id}/ | *ImageQueriesApi* | [**get_image**](docs/ImageQueriesApi.md#get_image) | **GET** /v1/image-queries/{id}/image | *ImageQueriesApi* | [**get_image_query**](docs/ImageQueriesApi.md#get_image_query) | **GET** /v1/image-queries/{id} | *ImageQueriesApi* | [**list_image_queries**](docs/ImageQueriesApi.md#list_image_queries) | **GET** /v1/image-queries | @@ -155,7 +155,6 @@ Class | Method | HTTP request | Description - [DetectorGroup](docs/DetectorGroup.md) - [DetectorGroupRequest](docs/DetectorGroupRequest.md) - [DetectorTypeEnum](docs/DetectorTypeEnum.md) - - [EdgeModelInfo](docs/EdgeModelInfo.md) - [EscalationTypeEnum](docs/EscalationTypeEnum.md) - [ImageQuery](docs/ImageQuery.md) - [ImageQueryTypeEnum](docs/ImageQueryTypeEnum.md) @@ -171,6 +170,8 @@ Class | Method | HTTP request | Description - [PaginatedImageQueryList](docs/PaginatedImageQueryList.md) - [PaginatedRuleList](docs/PaginatedRuleList.md) - [PatchedDetectorRequest](docs/PatchedDetectorRequest.md) + - [PayloadTemplate](docs/PayloadTemplate.md) + - [PayloadTemplateRequest](docs/PayloadTemplateRequest.md) - [ROI](docs/ROI.md) - [ROIRequest](docs/ROIRequest.md) - [ResultTypeEnum](docs/ResultTypeEnum.md) diff --git a/generated/docs/ActionsApi.md b/generated/docs/ActionsApi.md index 62acb205..9bf52c09 100644 --- a/generated/docs/ActionsApi.md +++ b/generated/docs/ActionsApi.md @@ -69,6 +69,7 @@ with groundlight_openapi_client.ApiClient(configuration) as api_client: WebhookActionRequest( url="url_example", include_image=True, + payload_template=None, ), ], ) # RuleRequest | diff --git a/generated/docs/Detector.md b/generated/docs/Detector.md index 133bfeba..97d08359 100644 --- a/generated/docs/Detector.md +++ b/generated/docs/Detector.md @@ -1,6 +1,6 @@ # Detector -Groundlight Detectors provide answers to natural language questions about images. Each detector can answer a single question, and multiple detectors can be strung together for more complex logic. Detectors can be created through the create_detector method, or through the create_[MODE]_detector methods for pro tier users +Spec for serializing a detector object in the public API. ## Properties Name | Type | Description | Notes diff --git a/generated/docs/ImageQuery.md b/generated/docs/ImageQuery.md index f7999986..83920b20 100644 --- a/generated/docs/ImageQuery.md +++ b/generated/docs/ImageQuery.md @@ -1,6 +1,6 @@ # ImageQuery -ImageQuery objects are the answers to natural language questions about images created by detectors. +Spec for serializing a image-query object in the public API. ## Properties Name | Type | Description | Notes diff --git a/generated/docs/PatchedDetectorRequest.md b/generated/docs/PatchedDetectorRequest.md index 819310b8..24dc3363 100644 --- a/generated/docs/PatchedDetectorRequest.md +++ b/generated/docs/PatchedDetectorRequest.md @@ -1,6 +1,6 @@ # PatchedDetectorRequest -Groundlight Detectors provide answers to natural language questions about images. Each detector can answer a single question, and multiple detectors can be strung together for more complex logic. Detectors can be created through the create_detector method, or through the create_[MODE]_detector methods for pro tier users +Spec for serializing a detector object in the public API. ## Properties Name | Type | Description | Notes diff --git a/generated/docs/PayloadTemplate.md b/generated/docs/PayloadTemplate.md new file mode 100644 index 00000000..a2c716c0 --- /dev/null +++ b/generated/docs/PayloadTemplate.md @@ -0,0 +1,12 @@ +# PayloadTemplate + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**template** | **str** | | +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/generated/docs/PayloadTemplateRequest.md b/generated/docs/PayloadTemplateRequest.md new file mode 100644 index 00000000..ff584274 --- /dev/null +++ b/generated/docs/PayloadTemplateRequest.md @@ -0,0 +1,12 @@ +# PayloadTemplateRequest + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**template** | **str** | | +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/generated/docs/WebhookAction.md b/generated/docs/WebhookAction.md index 639f1f7a..a1f6cf2b 100644 --- a/generated/docs/WebhookAction.md +++ b/generated/docs/WebhookAction.md @@ -6,6 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **url** | **str** | | **include_image** | **bool** | | [optional] +**payload_template** | **bool, date, datetime, dict, float, int, list, str, none_type** | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/generated/docs/WebhookActionRequest.md b/generated/docs/WebhookActionRequest.md index 411d192d..e3b1c59e 100644 --- a/generated/docs/WebhookActionRequest.md +++ b/generated/docs/WebhookActionRequest.md @@ -6,6 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **url** | **str** | | **include_image** | **bool** | | [optional] +**payload_template** | **bool, date, datetime, dict, float, int, list, str, none_type** | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/generated/groundlight_openapi_client/apis/__init__.py b/generated/groundlight_openapi_client/apis/__init__.py index 28edf7d0..ef5c1236 100644 --- a/generated/groundlight_openapi_client/apis/__init__.py +++ b/generated/groundlight_openapi_client/apis/__init__.py @@ -17,7 +17,6 @@ from groundlight_openapi_client.api.detector_groups_api import DetectorGroupsApi from groundlight_openapi_client.api.detector_reset_api import DetectorResetApi from groundlight_openapi_client.api.detectors_api import DetectorsApi -from groundlight_openapi_client.api.edge_api import EdgeApi from groundlight_openapi_client.api.image_queries_api import ImageQueriesApi from groundlight_openapi_client.api.labels_api import LabelsApi from groundlight_openapi_client.api.notes_api import NotesApi diff --git a/generated/groundlight_openapi_client/model/payload_template.py b/generated/groundlight_openapi_client/model/payload_template.py new file mode 100644 index 00000000..2cf74e03 --- /dev/null +++ b/generated/groundlight_openapi_client/model/payload_template.py @@ -0,0 +1,274 @@ +""" + Groundlight API + + Groundlight makes it simple to understand images. You can easily create computer vision detectors just by describing what you want to know using natural language. # noqa: E501 + + The version of the OpenAPI document: 0.18.2 + Contact: support@groundlight.ai + Generated by: https://openapi-generator.tech +""" + +import re # noqa: F401 +import sys # noqa: F401 + +from groundlight_openapi_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel, +) +from groundlight_openapi_client.exceptions import ApiAttributeError + + +class PayloadTemplate(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = {} + + validations = {} + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + return ( + bool, + date, + datetime, + dict, + float, + int, + list, + str, + none_type, + ) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + "template": (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + attribute_map = { + "template": "template", # noqa: E501 + } + + read_only_vars = {} + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, template, *args, **kwargs): # noqa: E501 + """PayloadTemplate - a model defined in OpenAPI + + Args: + template (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + _check_type = kwargs.pop("_check_type", True) + _spec_property_naming = kwargs.pop("_spec_property_naming", False) + _path_to_item = kwargs.pop("_path_to_item", ()) + _configuration = kwargs.pop("_configuration", None) + _visited_composed_classes = kwargs.pop("_visited_composed_classes", ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." + % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.template = template + for var_name, var_value in kwargs.items(): + if ( + var_name not in self.attribute_map + and self._configuration is not None + and self._configuration.discard_unknown_keys + and self.additional_properties_type is None + ): + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + "_data_store", + "_check_type", + "_spec_property_naming", + "_path_to_item", + "_configuration", + "_visited_composed_classes", + ]) + + @convert_js_args_to_python_args + def __init__(self, template, *args, **kwargs): # noqa: E501 + """PayloadTemplate - a model defined in OpenAPI + + Args: + template (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + _check_type = kwargs.pop("_check_type", True) + _spec_property_naming = kwargs.pop("_spec_property_naming", False) + _path_to_item = kwargs.pop("_path_to_item", ()) + _configuration = kwargs.pop("_configuration", None) + _visited_composed_classes = kwargs.pop("_visited_composed_classes", ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." + % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.template = template + for var_name, var_value in kwargs.items(): + if ( + var_name not in self.attribute_map + and self._configuration is not None + and self._configuration.discard_unknown_keys + and self.additional_properties_type is None + ): + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError( + f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + "class with read only attributes." + ) diff --git a/generated/groundlight_openapi_client/model/payload_template_request.py b/generated/groundlight_openapi_client/model/payload_template_request.py new file mode 100644 index 00000000..7e34645e --- /dev/null +++ b/generated/groundlight_openapi_client/model/payload_template_request.py @@ -0,0 +1,278 @@ +""" + Groundlight API + + Groundlight makes it simple to understand images. You can easily create computer vision detectors just by describing what you want to know using natural language. # noqa: E501 + + The version of the OpenAPI document: 0.18.2 + Contact: support@groundlight.ai + Generated by: https://openapi-generator.tech +""" + +import re # noqa: F401 +import sys # noqa: F401 + +from groundlight_openapi_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel, +) +from groundlight_openapi_client.exceptions import ApiAttributeError + + +class PayloadTemplateRequest(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = {} + + validations = { + ("template",): { + "min_length": 1, + }, + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + return ( + bool, + date, + datetime, + dict, + float, + int, + list, + str, + none_type, + ) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + "template": (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + attribute_map = { + "template": "template", # noqa: E501 + } + + read_only_vars = {} + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, template, *args, **kwargs): # noqa: E501 + """PayloadTemplateRequest - a model defined in OpenAPI + + Args: + template (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + _check_type = kwargs.pop("_check_type", True) + _spec_property_naming = kwargs.pop("_spec_property_naming", False) + _path_to_item = kwargs.pop("_path_to_item", ()) + _configuration = kwargs.pop("_configuration", None) + _visited_composed_classes = kwargs.pop("_visited_composed_classes", ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." + % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.template = template + for var_name, var_value in kwargs.items(): + if ( + var_name not in self.attribute_map + and self._configuration is not None + and self._configuration.discard_unknown_keys + and self.additional_properties_type is None + ): + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + "_data_store", + "_check_type", + "_spec_property_naming", + "_path_to_item", + "_configuration", + "_visited_composed_classes", + ]) + + @convert_js_args_to_python_args + def __init__(self, template, *args, **kwargs): # noqa: E501 + """PayloadTemplateRequest - a model defined in OpenAPI + + Args: + template (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + _check_type = kwargs.pop("_check_type", True) + _spec_property_naming = kwargs.pop("_spec_property_naming", False) + _path_to_item = kwargs.pop("_path_to_item", ()) + _configuration = kwargs.pop("_configuration", None) + _visited_composed_classes = kwargs.pop("_visited_composed_classes", ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." + % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.template = template + for var_name, var_value in kwargs.items(): + if ( + var_name not in self.attribute_map + and self._configuration is not None + and self._configuration.discard_unknown_keys + and self.additional_properties_type is None + ): + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError( + f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + "class with read only attributes." + ) diff --git a/generated/groundlight_openapi_client/model/webhook_action.py b/generated/groundlight_openapi_client/model/webhook_action.py index 826b3312..d272aad8 100644 --- a/generated/groundlight_openapi_client/model/webhook_action.py +++ b/generated/groundlight_openapi_client/model/webhook_action.py @@ -29,6 +29,12 @@ from groundlight_openapi_client.exceptions import ApiAttributeError +def lazy_import(): + from groundlight_openapi_client.model.payload_template import PayloadTemplate + + globals()["PayloadTemplate"] = PayloadTemplate + + class WebhookAction(ModelNormal): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -67,6 +73,7 @@ def additional_properties_type(): This must be a method because a model may have properties that are of type self, this must run after the class is loaded """ + lazy_import() return ( bool, date, @@ -91,9 +98,21 @@ def openapi_types(): openapi_types (dict): The key is attribute name and the value is attribute type. """ + lazy_import() return { "url": (str,), # noqa: E501 "include_image": (bool,), # noqa: E501 + "payload_template": ( + bool, + date, + datetime, + dict, + float, + int, + list, + str, + none_type, + ), # noqa: E501 } @cached_property @@ -103,6 +122,7 @@ def discriminator(): attribute_map = { "url": "url", # noqa: E501 "include_image": "include_image", # noqa: E501 + "payload_template": "payload_template", # noqa: E501 } read_only_vars = {} @@ -149,6 +169,7 @@ def _from_openapi_data(cls, url, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) include_image (bool): [optional] # noqa: E501 + payload_template (bool, date, datetime, dict, float, int, list, str, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) @@ -238,6 +259,7 @@ def __init__(self, url, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) include_image (bool): [optional] # noqa: E501 + payload_template (bool, date, datetime, dict, float, int, list, str, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) diff --git a/generated/groundlight_openapi_client/model/webhook_action_request.py b/generated/groundlight_openapi_client/model/webhook_action_request.py index 9990e3e0..053d1a77 100644 --- a/generated/groundlight_openapi_client/model/webhook_action_request.py +++ b/generated/groundlight_openapi_client/model/webhook_action_request.py @@ -29,6 +29,12 @@ from groundlight_openapi_client.exceptions import ApiAttributeError +def lazy_import(): + from groundlight_openapi_client.model.payload_template_request import PayloadTemplateRequest + + globals()["PayloadTemplateRequest"] = PayloadTemplateRequest + + class WebhookActionRequest(ModelNormal): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -68,6 +74,7 @@ def additional_properties_type(): This must be a method because a model may have properties that are of type self, this must run after the class is loaded """ + lazy_import() return ( bool, date, @@ -92,9 +99,21 @@ def openapi_types(): openapi_types (dict): The key is attribute name and the value is attribute type. """ + lazy_import() return { "url": (str,), # noqa: E501 "include_image": (bool,), # noqa: E501 + "payload_template": ( + bool, + date, + datetime, + dict, + float, + int, + list, + str, + none_type, + ), # noqa: E501 } @cached_property @@ -104,6 +123,7 @@ def discriminator(): attribute_map = { "url": "url", # noqa: E501 "include_image": "include_image", # noqa: E501 + "payload_template": "payload_template", # noqa: E501 } read_only_vars = {} @@ -150,6 +170,7 @@ def _from_openapi_data(cls, url, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) include_image (bool): [optional] # noqa: E501 + payload_template (bool, date, datetime, dict, float, int, list, str, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) @@ -239,6 +260,7 @@ def __init__(self, url, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) include_image (bool): [optional] # noqa: E501 + payload_template (bool, date, datetime, dict, float, int, list, str, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) diff --git a/generated/groundlight_openapi_client/models/__init__.py b/generated/groundlight_openapi_client/models/__init__.py index 3528a1aa..df058657 100644 --- a/generated/groundlight_openapi_client/models/__init__.py +++ b/generated/groundlight_openapi_client/models/__init__.py @@ -27,7 +27,6 @@ from groundlight_openapi_client.model.detector_group import DetectorGroup from groundlight_openapi_client.model.detector_group_request import DetectorGroupRequest from groundlight_openapi_client.model.detector_type_enum import DetectorTypeEnum -from groundlight_openapi_client.model.edge_model_info import EdgeModelInfo from groundlight_openapi_client.model.escalation_type_enum import EscalationTypeEnum from groundlight_openapi_client.model.image_query import ImageQuery from groundlight_openapi_client.model.image_query_type_enum import ImageQueryTypeEnum @@ -43,6 +42,8 @@ from groundlight_openapi_client.model.paginated_image_query_list import PaginatedImageQueryList from groundlight_openapi_client.model.paginated_rule_list import PaginatedRuleList from groundlight_openapi_client.model.patched_detector_request import PatchedDetectorRequest +from groundlight_openapi_client.model.payload_template import PayloadTemplate +from groundlight_openapi_client.model.payload_template_request import PayloadTemplateRequest from groundlight_openapi_client.model.roi import ROI from groundlight_openapi_client.model.roi_request import ROIRequest from groundlight_openapi_client.model.result_type_enum import ResultTypeEnum diff --git a/generated/model.py b/generated/model.py index 2a6062f9..458cafb0 100644 --- a/generated/model.py +++ b/generated/model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: public-api.yaml -# timestamp: 2025-02-08T00:46:39+00:00 +# timestamp: 2025-02-12T00:03:29+00:00 from __future__ import annotations @@ -62,20 +62,6 @@ class DetectorTypeEnum(str, Enum): detector = "detector" -class EdgeModelInfo(BaseModel): - """ - Information for the model running on edge, including temporary presigned urls to the model binaries - """ - - model_binary_id: Optional[str] = None - model_binary_url: Optional[str] = None - oodd_model_binary_id: Optional[str] = None - oodd_model_binary_url: Optional[str] = None - pipeline_config: Optional[Any] = None - oodd_pipeline_config: Optional[Any] = None - predictor_metadata: Optional[Any] = None - - class EscalationTypeEnum(str, Enum): """ * `STANDARD` - STANDARD @@ -109,6 +95,14 @@ class NoteRequest(BaseModel): image: Optional[bytes] = None +class PayloadTemplate(BaseModel): + template: str + + +class PayloadTemplateRequest(BaseModel): + template: constr(min_length=1) + + class ROI(BaseModel): """ Mixin for serializers to handle data in the StrictBaseModel format @@ -198,11 +192,13 @@ class VerbEnum(str, Enum): class WebhookAction(BaseModel): url: AnyUrl include_image: Optional[bool] = None + payload_template: Optional[PayloadTemplate] = None class WebhookActionRequest(BaseModel): url: AnyUrl include_image: Optional[bool] = None + payload_template: Optional[PayloadTemplateRequest] = None class Source(str, Enum): @@ -296,11 +292,7 @@ class ConditionRequest(BaseModel): class Detector(BaseModel): """ - Groundlight Detectors provide answers to natural language questions about images. - - Each detector can answer a single question, and multiple detectors can be strung together for - more complex logic. Detectors can be created through the create_detector method, or through the - create_[MODE]_detector methods for pro tier users + Spec for serializing a detector object in the public API. """ id: str = Field(..., description="A unique ID for this object.") @@ -374,7 +366,7 @@ class DetectorCreationInputRequest(BaseModel): class ImageQuery(BaseModel): """ - ImageQuery objects are the answers to natural language questions about images created by detectors. + Spec for serializing a image-query object in the public API. """ metadata: Optional[Dict[str, Any]] = Field(..., description="Metadata about the image query.") @@ -432,11 +424,7 @@ class PaginatedImageQueryList(BaseModel): class PatchedDetectorRequest(BaseModel): """ - Groundlight Detectors provide answers to natural language questions about images. - - Each detector can answer a single question, and multiple detectors can be strung together for - more complex logic. Detectors can be created through the create_detector method, or through the - create_[MODE]_detector methods for pro tier users + Spec for serializing a detector object in the public API. """ name: Optional[constr(min_length=1, max_length=200)] = Field( diff --git a/generated/test/test_payload_template.py b/generated/test/test_payload_template.py new file mode 100644 index 00000000..7d4af2fd --- /dev/null +++ b/generated/test/test_payload_template.py @@ -0,0 +1,35 @@ +""" + Groundlight API + + Groundlight makes it simple to understand images. You can easily create computer vision detectors just by describing what you want to know using natural language. # noqa: E501 + + The version of the OpenAPI document: 0.18.2 + Contact: support@groundlight.ai + Generated by: https://openapi-generator.tech +""" + +import sys +import unittest + +import groundlight_openapi_client +from groundlight_openapi_client.model.payload_template import PayloadTemplate + + +class TestPayloadTemplate(unittest.TestCase): + """PayloadTemplate unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testPayloadTemplate(self): + """Test PayloadTemplate""" + # FIXME: construct object with mandatory attributes with example values + # model = PayloadTemplate() # noqa: E501 + pass + + +if __name__ == "__main__": + unittest.main() diff --git a/generated/test/test_payload_template_request.py b/generated/test/test_payload_template_request.py new file mode 100644 index 00000000..312fc15c --- /dev/null +++ b/generated/test/test_payload_template_request.py @@ -0,0 +1,35 @@ +""" + Groundlight API + + Groundlight makes it simple to understand images. You can easily create computer vision detectors just by describing what you want to know using natural language. # noqa: E501 + + The version of the OpenAPI document: 0.18.2 + Contact: support@groundlight.ai + Generated by: https://openapi-generator.tech +""" + +import sys +import unittest + +import groundlight_openapi_client +from groundlight_openapi_client.model.payload_template_request import PayloadTemplateRequest + + +class TestPayloadTemplateRequest(unittest.TestCase): + """PayloadTemplateRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testPayloadTemplateRequest(self): + """Test PayloadTemplateRequest""" + # FIXME: construct object with mandatory attributes with example values + # model = PayloadTemplateRequest() # noqa: E501 + pass + + +if __name__ == "__main__": + unittest.main() diff --git a/spec/public-api.yaml b/spec/public-api.yaml index 78f51142..e6a3c735 100644 --- a/spec/public-api.yaml +++ b/spec/public-api.yaml @@ -320,28 +320,6 @@ paths: responses: '204': description: No response body - /v1/edge/fetch-model-urls/{detector_id}/: - get: - operationId: Get Model URLs - description: Gets time limited pre-authenticated URLs to download a detector's - edge model and oodd model. - parameters: - - in: path - name: detector_id - schema: - type: string - required: true - tags: - - edge - security: - - ApiToken: [] - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/EdgeModelInfo' - description: '' /v1/image-queries: get: operationId: List image queries @@ -728,12 +706,7 @@ components: - verb Detector: type: object - description: |- - Groundlight Detectors provide answers to natural language questions about images. - - Each detector can answer a single question, and multiple detectors can be strung together for - more complex logic. Detectors can be created through the create_detector method, or through the - create_[MODE]_detector methods for pro tier users + description: Spec for serializing a detector object in the public API. properties: id: type: string @@ -907,22 +880,6 @@ components: enum: - detector type: string - EdgeModelInfo: - type: object - description: Information for the model running on edge, including temporary - presigned urls to the model binaries - properties: - model_binary_id: - type: string - model_binary_url: - type: string - oodd_model_binary_id: - type: string - oodd_model_binary_url: - type: string - pipeline_config: {} - oodd_pipeline_config: {} - predictor_metadata: {} EscalationTypeEnum: enum: - STANDARD @@ -933,8 +890,7 @@ components: * `NO_HUMAN_LABELING` - NO_HUMAN_LABELING ImageQuery: type: object - description: ImageQuery objects are the answers to natural language questions - about images created by detectors. + description: Spec for serializing a image-query object in the public API. properties: metadata: type: object @@ -1198,12 +1154,7 @@ components: $ref: '#/components/schemas/Rule' PatchedDetectorRequest: type: object - description: |- - Groundlight Detectors provide answers to natural language questions about images. - - Each detector can answer a single question, and multiple detectors can be strung together for - more complex logic. Detectors can be created through the create_detector method, or through the - create_[MODE]_detector methods for pro tier users + description: Spec for serializing a detector object in the public API. properties: name: type: string @@ -1238,6 +1189,21 @@ components: * `STANDARD` - STANDARD * `NO_HUMAN_LABELING` - NO_HUMAN_LABELING x-internal: true + PayloadTemplate: + type: object + properties: + template: + type: string + required: + - template + PayloadTemplateRequest: + type: object + properties: + template: + type: string + minLength: 1 + required: + - template ROI: type: object description: Mixin for serializers to handle data in the StrictBaseModel format @@ -1422,6 +1388,10 @@ components: maxLength: 200 include_image: type: boolean + payload_template: + allOf: + - $ref: '#/components/schemas/PayloadTemplate' + nullable: true required: - url WebhookActionRequest: @@ -1434,6 +1404,10 @@ components: maxLength: 200 include_image: type: boolean + payload_template: + allOf: + - $ref: '#/components/schemas/PayloadTemplateRequest' + nullable: true required: - url BinaryClassificationResult: From 6f385c222a0a174ce6bdef81212a9b7a7314a300 Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Wed, 12 Feb 2025 00:19:54 +0000 Subject: [PATCH 02/12] initial manual changes --- docs/docs/guide/9-alerts.md | 2 +- src/groundlight/experimental_api.py | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/docs/guide/9-alerts.md b/docs/docs/guide/9-alerts.md index 67c6d877..2adbb61f 100644 --- a/docs/docs/guide/9-alerts.md +++ b/docs/docs/guide/9-alerts.md @@ -24,4 +24,4 @@ Consider configuring a "no queries submitted" alert to monitor system health. If ## Alert Mediums -Groundlight supports the following alerts via Email and Text Message (SMS), with webhook support coming soon. +Groundlight supports the following alerts via Email, Text Message (SMS), and Webhooks. diff --git a/src/groundlight/experimental_api.py b/src/groundlight/experimental_api.py index b9fecac2..c39b3a49 100644 --- a/src/groundlight/experimental_api.py +++ b/src/groundlight/experimental_api.py @@ -30,6 +30,7 @@ from groundlight_openapi_client.model.status_enum import StatusEnum from groundlight_openapi_client.model.verb_enum import VerbEnum from groundlight_openapi_client.model.webhook_action_request import WebhookActionRequest +from groundlight_openapi_client.model.payload_template_request import PayloadTemplateRequest from model import ( ROI, Action, @@ -43,6 +44,7 @@ PaginatedRuleList, Rule, WebhookAction, + PayloadTemplate, ) from groundlight.images import parse_supported_image_types @@ -163,7 +165,7 @@ def make_action( include_image=include_image, ) - def make_webhook_action(self, url: str, include_image: bool) -> WebhookAction: + def make_webhook_action(self, url: str, include_image: bool, payload_template: Optional[str] = None) -> WebhookAction: """ Creates a WebhookAction object for use in creating alerts This function serves as a convenience method; WebhookAction objects can also be created directly. @@ -173,10 +175,14 @@ def make_webhook_action(self, url: str, include_image: bool) -> WebhookAction: action = gl.make_webhook_action("https://example.com/webhook", include_image=True) :param url: The URL to send the webhook to :param include_image: Whether to include the triggering image in the webhook payload + :param payload_template: Optional custom template for the webhook payload. The template will be rendered with + the alert data. The template must be a valid Jinja2 template which produces valid JSON when rendered. If no + template is provided, the default template designed for Slack will be used. """ return WebhookAction( url=str(url), include_image=include_image, + payload_template=PayloadTemplate(template=payload_template), ) def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa: PLR0913 @@ -266,6 +272,7 @@ def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa WebhookActionRequest( url=str(webhook_action.url), include_image=webhook_action.include_image, + payload_template=PayloadTemplateRequest(template=webhook_action.payload_template) if webhook_action.payload_template else None, ) for webhook_action in webhook_actions ] From 06a65aa22baf558e29bed2ba3d2dd28dddee0a98 Mon Sep 17 00:00:00 2001 From: Auto-format Bot Date: Wed, 12 Feb 2025 00:20:47 +0000 Subject: [PATCH 03/12] Automatically reformatting code --- src/groundlight/experimental_api.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/groundlight/experimental_api.py b/src/groundlight/experimental_api.py index c39b3a49..8070f491 100644 --- a/src/groundlight/experimental_api.py +++ b/src/groundlight/experimental_api.py @@ -26,11 +26,11 @@ from groundlight_openapi_client.model.escalation_type_enum import EscalationTypeEnum from groundlight_openapi_client.model.multi_class_mode_configuration import MultiClassModeConfiguration from groundlight_openapi_client.model.patched_detector_request import PatchedDetectorRequest +from groundlight_openapi_client.model.payload_template_request import PayloadTemplateRequest from groundlight_openapi_client.model.rule_request import RuleRequest from groundlight_openapi_client.model.status_enum import StatusEnum from groundlight_openapi_client.model.verb_enum import VerbEnum from groundlight_openapi_client.model.webhook_action_request import WebhookActionRequest -from groundlight_openapi_client.model.payload_template_request import PayloadTemplateRequest from model import ( ROI, Action, @@ -42,9 +42,9 @@ EdgeModelInfo, ModeEnum, PaginatedRuleList, + PayloadTemplate, Rule, WebhookAction, - PayloadTemplate, ) from groundlight.images import parse_supported_image_types @@ -165,7 +165,9 @@ def make_action( include_image=include_image, ) - def make_webhook_action(self, url: str, include_image: bool, payload_template: Optional[str] = None) -> WebhookAction: + def make_webhook_action( + self, url: str, include_image: bool, payload_template: Optional[str] = None + ) -> WebhookAction: """ Creates a WebhookAction object for use in creating alerts This function serves as a convenience method; WebhookAction objects can also be created directly. @@ -272,7 +274,11 @@ def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa WebhookActionRequest( url=str(webhook_action.url), include_image=webhook_action.include_image, - payload_template=PayloadTemplateRequest(template=webhook_action.payload_template) if webhook_action.payload_template else None, + payload_template=( + PayloadTemplateRequest(template=webhook_action.payload_template) + if webhook_action.payload_template + else None + ), ) for webhook_action in webhook_actions ] From 04db183cad635db220d57ef400bee88eef4a2a03 Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Wed, 12 Feb 2025 19:01:24 +0000 Subject: [PATCH 04/12] regenerate --- generated/.openapi-generator/FILES | 6 +- generated/README.md | 2 + generated/docs/Detector.md | 2 +- generated/docs/ImageQuery.md | 2 +- generated/docs/PatchedDetectorRequest.md | 2 +- .../apis/__init__.py | 1 + .../models/__init__.py | 1 + generated/model.py | 30 ++++++++-- spec/public-api.yaml | 55 ++++++++++++++++++- src/groundlight/experimental_api.py | 12 +++- test/unit/test_actions.py | 2 +- 11 files changed, 99 insertions(+), 16 deletions(-) diff --git a/generated/.openapi-generator/FILES b/generated/.openapi-generator/FILES index a9c92fcf..a37a75e0 100644 --- a/generated/.openapi-generator/FILES +++ b/generated/.openapi-generator/FILES @@ -22,6 +22,8 @@ docs/DetectorGroupsApi.md docs/DetectorResetApi.md docs/DetectorTypeEnum.md docs/DetectorsApi.md +docs/EdgeApi.md +docs/EdgeModelInfo.md docs/EscalationTypeEnum.md docs/ImageQueriesApi.md docs/ImageQuery.md @@ -62,6 +64,7 @@ groundlight_openapi_client/api/actions_api.py groundlight_openapi_client/api/detector_groups_api.py groundlight_openapi_client/api/detector_reset_api.py groundlight_openapi_client/api/detectors_api.py +groundlight_openapi_client/api/edge_api.py groundlight_openapi_client/api/image_queries_api.py groundlight_openapi_client/api/labels_api.py groundlight_openapi_client/api/notes_api.py @@ -89,6 +92,7 @@ groundlight_openapi_client/model/detector_creation_input_request.py groundlight_openapi_client/model/detector_group.py groundlight_openapi_client/model/detector_group_request.py groundlight_openapi_client/model/detector_type_enum.py +groundlight_openapi_client/model/edge_model_info.py groundlight_openapi_client/model/escalation_type_enum.py groundlight_openapi_client/model/image_query.py groundlight_openapi_client/model/image_query_type_enum.py @@ -126,6 +130,4 @@ setup.cfg setup.py test-requirements.txt test/__init__.py -test/test_payload_template.py -test/test_payload_template_request.py tox.ini diff --git a/generated/README.md b/generated/README.md index 28f94663..66cea9f2 100644 --- a/generated/README.md +++ b/generated/README.md @@ -125,6 +125,7 @@ Class | Method | HTTP request | Description *DetectorsApi* | [**get_detector**](docs/DetectorsApi.md#get_detector) | **GET** /v1/detectors/{id} | *DetectorsApi* | [**list_detectors**](docs/DetectorsApi.md#list_detectors) | **GET** /v1/detectors | *DetectorsApi* | [**update_detector**](docs/DetectorsApi.md#update_detector) | **PATCH** /v1/detectors/{id} | +*EdgeApi* | [**get_model_urls**](docs/EdgeApi.md#get_model_urls) | **GET** /v1/edge/fetch-model-urls/{detector_id}/ | *ImageQueriesApi* | [**get_image**](docs/ImageQueriesApi.md#get_image) | **GET** /v1/image-queries/{id}/image | *ImageQueriesApi* | [**get_image_query**](docs/ImageQueriesApi.md#get_image_query) | **GET** /v1/image-queries/{id} | *ImageQueriesApi* | [**list_image_queries**](docs/ImageQueriesApi.md#list_image_queries) | **GET** /v1/image-queries | @@ -155,6 +156,7 @@ Class | Method | HTTP request | Description - [DetectorGroup](docs/DetectorGroup.md) - [DetectorGroupRequest](docs/DetectorGroupRequest.md) - [DetectorTypeEnum](docs/DetectorTypeEnum.md) + - [EdgeModelInfo](docs/EdgeModelInfo.md) - [EscalationTypeEnum](docs/EscalationTypeEnum.md) - [ImageQuery](docs/ImageQuery.md) - [ImageQueryTypeEnum](docs/ImageQueryTypeEnum.md) diff --git a/generated/docs/Detector.md b/generated/docs/Detector.md index 97d08359..133bfeba 100644 --- a/generated/docs/Detector.md +++ b/generated/docs/Detector.md @@ -1,6 +1,6 @@ # Detector -Spec for serializing a detector object in the public API. +Groundlight Detectors provide answers to natural language questions about images. Each detector can answer a single question, and multiple detectors can be strung together for more complex logic. Detectors can be created through the create_detector method, or through the create_[MODE]_detector methods for pro tier users ## Properties Name | Type | Description | Notes diff --git a/generated/docs/ImageQuery.md b/generated/docs/ImageQuery.md index 83920b20..f7999986 100644 --- a/generated/docs/ImageQuery.md +++ b/generated/docs/ImageQuery.md @@ -1,6 +1,6 @@ # ImageQuery -Spec for serializing a image-query object in the public API. +ImageQuery objects are the answers to natural language questions about images created by detectors. ## Properties Name | Type | Description | Notes diff --git a/generated/docs/PatchedDetectorRequest.md b/generated/docs/PatchedDetectorRequest.md index 24dc3363..819310b8 100644 --- a/generated/docs/PatchedDetectorRequest.md +++ b/generated/docs/PatchedDetectorRequest.md @@ -1,6 +1,6 @@ # PatchedDetectorRequest -Spec for serializing a detector object in the public API. +Groundlight Detectors provide answers to natural language questions about images. Each detector can answer a single question, and multiple detectors can be strung together for more complex logic. Detectors can be created through the create_detector method, or through the create_[MODE]_detector methods for pro tier users ## Properties Name | Type | Description | Notes diff --git a/generated/groundlight_openapi_client/apis/__init__.py b/generated/groundlight_openapi_client/apis/__init__.py index ef5c1236..28edf7d0 100644 --- a/generated/groundlight_openapi_client/apis/__init__.py +++ b/generated/groundlight_openapi_client/apis/__init__.py @@ -17,6 +17,7 @@ from groundlight_openapi_client.api.detector_groups_api import DetectorGroupsApi from groundlight_openapi_client.api.detector_reset_api import DetectorResetApi from groundlight_openapi_client.api.detectors_api import DetectorsApi +from groundlight_openapi_client.api.edge_api import EdgeApi from groundlight_openapi_client.api.image_queries_api import ImageQueriesApi from groundlight_openapi_client.api.labels_api import LabelsApi from groundlight_openapi_client.api.notes_api import NotesApi diff --git a/generated/groundlight_openapi_client/models/__init__.py b/generated/groundlight_openapi_client/models/__init__.py index df058657..70a18ca9 100644 --- a/generated/groundlight_openapi_client/models/__init__.py +++ b/generated/groundlight_openapi_client/models/__init__.py @@ -27,6 +27,7 @@ from groundlight_openapi_client.model.detector_group import DetectorGroup from groundlight_openapi_client.model.detector_group_request import DetectorGroupRequest from groundlight_openapi_client.model.detector_type_enum import DetectorTypeEnum +from groundlight_openapi_client.model.edge_model_info import EdgeModelInfo from groundlight_openapi_client.model.escalation_type_enum import EscalationTypeEnum from groundlight_openapi_client.model.image_query import ImageQuery from groundlight_openapi_client.model.image_query_type_enum import ImageQueryTypeEnum diff --git a/generated/model.py b/generated/model.py index 458cafb0..5b83116d 100644 --- a/generated/model.py +++ b/generated/model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: public-api.yaml -# timestamp: 2025-02-12T00:03:29+00:00 +# timestamp: 2025-02-12T18:00:35+00:00 from __future__ import annotations @@ -62,6 +62,20 @@ class DetectorTypeEnum(str, Enum): detector = "detector" +class EdgeModelInfo(BaseModel): + """ + Information for the model running on edge, including temporary presigned urls to the model binaries + """ + + model_binary_id: Optional[str] = None + model_binary_url: Optional[str] = None + oodd_model_binary_id: Optional[str] = None + oodd_model_binary_url: Optional[str] = None + pipeline_config: Optional[Any] = None + oodd_pipeline_config: Optional[Any] = None + predictor_metadata: Optional[Any] = None + + class EscalationTypeEnum(str, Enum): """ * `STANDARD` - STANDARD @@ -292,7 +306,11 @@ class ConditionRequest(BaseModel): class Detector(BaseModel): """ - Spec for serializing a detector object in the public API. + Groundlight Detectors provide answers to natural language questions about images. + + Each detector can answer a single question, and multiple detectors can be strung together for + more complex logic. Detectors can be created through the create_detector method, or through the + create_[MODE]_detector methods for pro tier users """ id: str = Field(..., description="A unique ID for this object.") @@ -366,7 +384,7 @@ class DetectorCreationInputRequest(BaseModel): class ImageQuery(BaseModel): """ - Spec for serializing a image-query object in the public API. + ImageQuery objects are the answers to natural language questions about images created by detectors. """ metadata: Optional[Dict[str, Any]] = Field(..., description="Metadata about the image query.") @@ -424,7 +442,11 @@ class PaginatedImageQueryList(BaseModel): class PatchedDetectorRequest(BaseModel): """ - Spec for serializing a detector object in the public API. + Groundlight Detectors provide answers to natural language questions about images. + + Each detector can answer a single question, and multiple detectors can be strung together for + more complex logic. Detectors can be created through the create_detector method, or through the + create_[MODE]_detector methods for pro tier users """ name: Optional[constr(min_length=1, max_length=200)] = Field( diff --git a/spec/public-api.yaml b/spec/public-api.yaml index e6a3c735..4ddb7244 100644 --- a/spec/public-api.yaml +++ b/spec/public-api.yaml @@ -320,6 +320,28 @@ paths: responses: '204': description: No response body + /v1/edge/fetch-model-urls/{detector_id}/: + get: + operationId: Get Model URLs + description: Gets time limited pre-authenticated URLs to download a detector's + edge model and oodd model. + parameters: + - in: path + name: detector_id + schema: + type: string + required: true + tags: + - edge + security: + - ApiToken: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/EdgeModelInfo' + description: '' /v1/image-queries: get: operationId: List image queries @@ -706,7 +728,12 @@ components: - verb Detector: type: object - description: Spec for serializing a detector object in the public API. + description: |- + Groundlight Detectors provide answers to natural language questions about images. + + Each detector can answer a single question, and multiple detectors can be strung together for + more complex logic. Detectors can be created through the create_detector method, or through the + create_[MODE]_detector methods for pro tier users properties: id: type: string @@ -880,6 +907,22 @@ components: enum: - detector type: string + EdgeModelInfo: + type: object + description: Information for the model running on edge, including temporary + presigned urls to the model binaries + properties: + model_binary_id: + type: string + model_binary_url: + type: string + oodd_model_binary_id: + type: string + oodd_model_binary_url: + type: string + pipeline_config: {} + oodd_pipeline_config: {} + predictor_metadata: {} EscalationTypeEnum: enum: - STANDARD @@ -890,7 +933,8 @@ components: * `NO_HUMAN_LABELING` - NO_HUMAN_LABELING ImageQuery: type: object - description: Spec for serializing a image-query object in the public API. + description: ImageQuery objects are the answers to natural language questions + about images created by detectors. properties: metadata: type: object @@ -1154,7 +1198,12 @@ components: $ref: '#/components/schemas/Rule' PatchedDetectorRequest: type: object - description: Spec for serializing a detector object in the public API. + description: |- + Groundlight Detectors provide answers to natural language questions about images. + + Each detector can answer a single question, and multiple detectors can be strung together for + more complex logic. Detectors can be created through the create_detector method, or through the + create_[MODE]_detector methods for pro tier users properties: name: type: string diff --git a/src/groundlight/experimental_api.py b/src/groundlight/experimental_api.py index c39b3a49..b6576eef 100644 --- a/src/groundlight/experimental_api.py +++ b/src/groundlight/experimental_api.py @@ -165,7 +165,9 @@ def make_action( include_image=include_image, ) - def make_webhook_action(self, url: str, include_image: bool, payload_template: Optional[str] = None) -> WebhookAction: + def make_webhook_action( + self, url: str, include_image: bool, payload_template: Optional[str] = None + ) -> WebhookAction: """ Creates a WebhookAction object for use in creating alerts This function serves as a convenience method; WebhookAction objects can also be created directly. @@ -182,7 +184,7 @@ def make_webhook_action(self, url: str, include_image: bool, payload_template: O return WebhookAction( url=str(url), include_image=include_image, - payload_template=PayloadTemplate(template=payload_template), + payload_template=payload_template, ) def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa: PLR0913 @@ -272,7 +274,11 @@ def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa WebhookActionRequest( url=str(webhook_action.url), include_image=webhook_action.include_image, - payload_template=PayloadTemplateRequest(template=webhook_action.payload_template) if webhook_action.payload_template else None, + payload_template=( + PayloadTemplateRequest(template=webhook_action.payload_template) + if webhook_action.payload_template + else None + ), ) for webhook_action in webhook_actions ] diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index 65055c51..cf843221 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -108,4 +108,4 @@ def test_create_alert_webhook_action_and_other_action(gl_experimental: Experimen det, f"test_alert_{name}", condition, webhook_actions=webhook_action, actions=email_action ) assert len(alert.webhook_action) == 1 - assert len(alert.action.root) == 1 + assert len(alert.action.root) == 1 \ No newline at end of file From e6d4a5fe5282924275da0efa990fd7be3acd587e Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Wed, 12 Feb 2025 19:50:35 +0000 Subject: [PATCH 05/12] fix template parsing --- src/groundlight/experimental_api.py | 10 ++++++++-- test/unit/test_actions.py | 13 ++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/groundlight/experimental_api.py b/src/groundlight/experimental_api.py index b6576eef..ec9a747f 100644 --- a/src/groundlight/experimental_api.py +++ b/src/groundlight/experimental_api.py @@ -166,7 +166,7 @@ def make_action( ) def make_webhook_action( - self, url: str, include_image: bool, payload_template: Optional[str] = None + self, url: str, include_image: bool, payload_template: Optional[PayloadTemplate] = None ) -> WebhookAction: """ Creates a WebhookAction object for use in creating alerts @@ -187,6 +187,12 @@ def make_webhook_action( payload_template=payload_template, ) + def make_payload_template(self, template: str) -> PayloadTemplate: + """ + Creates a PayloadTemplate object for use in creating alerts + """ + return PayloadTemplate(template=template) + def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa: PLR0913 self, detector: Union[str, Detector], @@ -275,7 +281,7 @@ def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa url=str(webhook_action.url), include_image=webhook_action.include_image, payload_template=( - PayloadTemplateRequest(template=webhook_action.payload_template) + PayloadTemplateRequest(template=webhook_action.payload_template.template) if webhook_action.payload_template else None ), diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index cf843221..6f473405 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -108,4 +108,15 @@ def test_create_alert_webhook_action_and_other_action(gl_experimental: Experimen det, f"test_alert_{name}", condition, webhook_actions=webhook_action, actions=email_action ) assert len(alert.webhook_action) == 1 - assert len(alert.action.root) == 1 \ No newline at end of file + assert len(alert.action.root) == 1 + +def test_create_alert_webhook_action_with_payload_template(gl_experimental: ExperimentalApi): + name = f"Test {datetime.utcnow()}" + det = gl_experimental.get_or_create_detector(name, "test_query") + condition = gl_experimental.make_condition("CHANGED_TO", {"label": "YES"}) + payload_template = gl_experimental.make_payload_template("{\"text\": \"This should be a valid payload\"}") + webhook_action = gl_experimental.make_webhook_action("https://groundlight.ai", include_image=True, payload_template=payload_template) + alert = gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) + + assert len(alert.webhook_action) == 1 + assert alert.webhook_action[0].payload_template.template == "{\"text\": \"This should be a valid payload\"}" \ No newline at end of file From 86e40a0d89543173adad057c47e5d3ec081dc685 Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Wed, 12 Feb 2025 20:00:43 +0000 Subject: [PATCH 06/12] add validation checks --- test/unit/test_actions.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index 6f473405..7adf3577 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -119,4 +119,22 @@ def test_create_alert_webhook_action_with_payload_template(gl_experimental: Expe alert = gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) assert len(alert.webhook_action) == 1 - assert alert.webhook_action[0].payload_template.template == "{\"text\": \"This should be a valid payload\"}" \ No newline at end of file + assert alert.webhook_action[0].payload_template.template == "{\"text\": \"This should be a valid payload\"}" + +def test_create_alert_webhook_action_with_invalid_payload_template(gl_experimental: ExperimentalApi): + name = f"Test {datetime.utcnow()}" + det = gl_experimental.get_or_create_detector(name, "test_query") + condition = gl_experimental.make_condition("CHANGED_TO", {"label": "YES"}) + payload_template = gl_experimental.make_payload_template("{\"text\": \"This should not be a valid payload, jinja brackets are not closed properly {{detector_id}\"}") + webhook_action = gl_experimental.make_webhook_action("https://groundlight.ai", include_image=True, payload_template=payload_template) + + with pytest.raises(Exception) as e: + gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) + assert e.value.status_code == 400 + + payload_template = gl_experimental.make_payload_template("This should not be a valid payload, it's valid jinja but won't produce valid json") + webhook_action = gl_experimental.make_webhook_action("https://groundlight.ai", include_image=True, payload_template=payload_template) + + with pytest.raises(Exception) as e: + gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) + assert e.value.status_code == 400 From 3d0343b4e6028be66616a8c4ebba3430dc854a02 Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Wed, 12 Feb 2025 21:49:38 +0000 Subject: [PATCH 07/12] small test changes --- test/unit/test_actions.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index 7adf3577..90c1d24b 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -90,8 +90,8 @@ def test_create_alert_multiple_webhook_actions(gl_experimental: ExperimentalApi) name = f"Test {datetime.utcnow()}" det = gl_experimental.get_or_create_detector(name, "test_query") condition = gl_experimental.make_condition("CHANGED_TO", {"label": "YES"}) - webhook_action_1 = gl_experimental.make_webhook_action("https://groundlight.ai", include_image=True) - webhook_action_2 = gl_experimental.make_webhook_action("https://example.com/webhook", include_image=False) + webhook_action_1 = gl_experimental.make_webhook_action(url="https://groundlight.ai", include_image=True) + webhook_action_2 = gl_experimental.make_webhook_action(url="https://example.com/webhook", include_image=False) webhook_actions = [webhook_action_1, webhook_action_2] alert = gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_actions) assert len(alert.webhook_action) == len(webhook_actions) @@ -102,7 +102,7 @@ def test_create_alert_webhook_action_and_other_action(gl_experimental: Experimen name = f"Test {datetime.utcnow()}" det = gl_experimental.get_or_create_detector(name, "test_query") condition = gl_experimental.make_condition("CHANGED_TO", {"label": "YES"}) - webhook_action = gl_experimental.make_webhook_action("https://groundlight.ai", include_image=True) + webhook_action = gl_experimental.make_webhook_action(url="https://groundlight.ai", include_image=True) email_action = gl_experimental.make_action("EMAIL", "test@groundlight.ai", False) alert = gl_experimental.create_alert( det, f"test_alert_{name}", condition, webhook_actions=webhook_action, actions=email_action @@ -115,7 +115,7 @@ def test_create_alert_webhook_action_with_payload_template(gl_experimental: Expe det = gl_experimental.get_or_create_detector(name, "test_query") condition = gl_experimental.make_condition("CHANGED_TO", {"label": "YES"}) payload_template = gl_experimental.make_payload_template("{\"text\": \"This should be a valid payload\"}") - webhook_action = gl_experimental.make_webhook_action("https://groundlight.ai", include_image=True, payload_template=payload_template) + webhook_action = gl_experimental.make_webhook_action(url="https://hooks.slack.com/services/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", include_image=True, payload_template=payload_template) alert = gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) assert len(alert.webhook_action) == 1 @@ -126,14 +126,14 @@ def test_create_alert_webhook_action_with_invalid_payload_template(gl_experiment det = gl_experimental.get_or_create_detector(name, "test_query") condition = gl_experimental.make_condition("CHANGED_TO", {"label": "YES"}) payload_template = gl_experimental.make_payload_template("{\"text\": \"This should not be a valid payload, jinja brackets are not closed properly {{detector_id}\"}") - webhook_action = gl_experimental.make_webhook_action("https://groundlight.ai", include_image=True, payload_template=payload_template) + webhook_action = gl_experimental.make_webhook_action(url="https://groundlight.ai", include_image=True, payload_template=payload_template) with pytest.raises(Exception) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) assert e.value.status_code == 400 payload_template = gl_experimental.make_payload_template("This should not be a valid payload, it's valid jinja but won't produce valid json") - webhook_action = gl_experimental.make_webhook_action("https://groundlight.ai", include_image=True, payload_template=payload_template) + webhook_action = gl_experimental.make_webhook_action(url="https://groundlight.ai", include_image=True, payload_template=payload_template) with pytest.raises(Exception) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) From 89f0159f4f0e037f1864fffb112f33036fd61dea Mon Sep 17 00:00:00 2001 From: Auto-format Bot Date: Wed, 12 Feb 2025 22:08:31 +0000 Subject: [PATCH 08/12] Automatically reformatting code --- test/unit/test_actions.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index 90c1d24b..17496dd9 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -110,30 +110,44 @@ def test_create_alert_webhook_action_and_other_action(gl_experimental: Experimen assert len(alert.webhook_action) == 1 assert len(alert.action.root) == 1 + def test_create_alert_webhook_action_with_payload_template(gl_experimental: ExperimentalApi): name = f"Test {datetime.utcnow()}" det = gl_experimental.get_or_create_detector(name, "test_query") condition = gl_experimental.make_condition("CHANGED_TO", {"label": "YES"}) - payload_template = gl_experimental.make_payload_template("{\"text\": \"This should be a valid payload\"}") - webhook_action = gl_experimental.make_webhook_action(url="https://hooks.slack.com/services/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", include_image=True, payload_template=payload_template) + payload_template = gl_experimental.make_payload_template('{"text": "This should be a valid payload"}') + webhook_action = gl_experimental.make_webhook_action( + url="https://hooks.slack.com/services/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", + include_image=True, + payload_template=payload_template, + ) alert = gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) assert len(alert.webhook_action) == 1 - assert alert.webhook_action[0].payload_template.template == "{\"text\": \"This should be a valid payload\"}" + assert alert.webhook_action[0].payload_template.template == '{"text": "This should be a valid payload"}' + def test_create_alert_webhook_action_with_invalid_payload_template(gl_experimental: ExperimentalApi): name = f"Test {datetime.utcnow()}" det = gl_experimental.get_or_create_detector(name, "test_query") condition = gl_experimental.make_condition("CHANGED_TO", {"label": "YES"}) - payload_template = gl_experimental.make_payload_template("{\"text\": \"This should not be a valid payload, jinja brackets are not closed properly {{detector_id}\"}") - webhook_action = gl_experimental.make_webhook_action(url="https://groundlight.ai", include_image=True, payload_template=payload_template) + payload_template = gl_experimental.make_payload_template( + '{"text": "This should not be a valid payload, jinja brackets are not closed properly {{detector_id}"}' + ) + webhook_action = gl_experimental.make_webhook_action( + url="https://groundlight.ai", include_image=True, payload_template=payload_template + ) with pytest.raises(Exception) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) assert e.value.status_code == 400 - payload_template = gl_experimental.make_payload_template("This should not be a valid payload, it's valid jinja but won't produce valid json") - webhook_action = gl_experimental.make_webhook_action(url="https://groundlight.ai", include_image=True, payload_template=payload_template) + payload_template = gl_experimental.make_payload_template( + "This should not be a valid payload, it's valid jinja but won't produce valid json" + ) + webhook_action = gl_experimental.make_webhook_action( + url="https://groundlight.ai", include_image=True, payload_template=payload_template + ) with pytest.raises(Exception) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) From d3d131ea3b5031f9d26b85a9ed5608fbb2901f16 Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Sat, 22 Feb 2025 01:22:26 +0000 Subject: [PATCH 09/12] fixed bad tests --- test/unit/test_actions.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index 17496dd9..3f8b0fb0 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -1,7 +1,7 @@ from datetime import datetime import pytest -from groundlight import ExperimentalApi +from groundlight import ExperimentalApi, ApiException from groundlight_openapi_client.exceptions import NotFoundException @@ -138,9 +138,9 @@ def test_create_alert_webhook_action_with_invalid_payload_template(gl_experiment url="https://groundlight.ai", include_image=True, payload_template=payload_template ) - with pytest.raises(Exception) as e: + with pytest.raises(ApiException) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) - assert e.value.status_code == 400 + assert e.value.status == 400 payload_template = gl_experimental.make_payload_template( "This should not be a valid payload, it's valid jinja but won't produce valid json" @@ -149,6 +149,6 @@ def test_create_alert_webhook_action_with_invalid_payload_template(gl_experiment url="https://groundlight.ai", include_image=True, payload_template=payload_template ) - with pytest.raises(Exception) as e: + with pytest.raises(ApiException) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) - assert e.value.status_code == 400 + assert e.value.status == 400 From 58316db09b32c0ec4a247f289ceb813bf28d1d27 Mon Sep 17 00:00:00 2001 From: Auto-format Bot Date: Sat, 22 Feb 2025 01:23:17 +0000 Subject: [PATCH 10/12] Automatically reformatting code --- test/unit/test_actions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index 3f8b0fb0..47750099 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -1,7 +1,7 @@ from datetime import datetime import pytest -from groundlight import ExperimentalApi, ApiException +from groundlight import ApiException, ExperimentalApi from groundlight_openapi_client.exceptions import NotFoundException From 58ebc115aabe2848481c03e2a9901d5629ab710c Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Sat, 22 Feb 2025 01:28:08 +0000 Subject: [PATCH 11/12] pylint --- src/groundlight/experimental_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/groundlight/experimental_api.py b/src/groundlight/experimental_api.py index 2f787b64..ca297f10 100644 --- a/src/groundlight/experimental_api.py +++ b/src/groundlight/experimental_api.py @@ -1,3 +1,4 @@ +# pylint: disable=too-many-lines """ experimental_api.py From 219563ab6913bbb3ac0bf4c83f8338525d8c6d9d Mon Sep 17 00:00:00 2001 From: Francine Wright Date: Sat, 22 Feb 2025 01:32:16 +0000 Subject: [PATCH 12/12] ok now i'm annoyed --- test/unit/test_actions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index 47750099..eb6bf1ee 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -138,9 +138,11 @@ def test_create_alert_webhook_action_with_invalid_payload_template(gl_experiment url="https://groundlight.ai", include_image=True, payload_template=payload_template ) + bad_request_exception_status_code = 400 + with pytest.raises(ApiException) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) - assert e.value.status == 400 + assert e.value.status == bad_request_exception_status_code payload_template = gl_experimental.make_payload_template( "This should not be a valid payload, it's valid jinja but won't produce valid json" @@ -151,4 +153,4 @@ def test_create_alert_webhook_action_with_invalid_payload_template(gl_experiment with pytest.raises(ApiException) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) - assert e.value.status == 400 + assert e.value.status == bad_request_exception_status_code