diff --git a/generated/docs/CountModeConfiguration.md b/generated/docs/CountModeConfiguration.md index b576a6d8..0262ae0a 100644 --- a/generated/docs/CountModeConfiguration.md +++ b/generated/docs/CountModeConfiguration.md @@ -4,6 +4,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**class_name** | **str** | | **max_count** | **int** | | [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] diff --git a/generated/docs/ImageQueriesApi.md b/generated/docs/ImageQueriesApi.md index 3d6cd5b8..7f39a4da 100644 --- a/generated/docs/ImageQueriesApi.md +++ b/generated/docs/ImageQueriesApi.md @@ -282,6 +282,7 @@ 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 | Choose a detector by its ID. + confidence_threshold = 0 # float | The confidence threshold for the image query. (optional) human_review = "human_review_example" # str | If set to `DEFAULT`, use the regular escalation logic (i.e., send the image query for human review if the ML model is not confident). If set to `ALWAYS`, always send the image query for human review even if the ML model is confident. If set to `NEVER`, never send the image query for human review even if the ML model is not confident. (optional) image_query_id = "image_query_id_example" # str | The ID to assign to the created image query. (optional) inspection_id = "inspection_id_example" # str | Associate the image query with an inspection. (optional) @@ -300,7 +301,7 @@ with groundlight_openapi_client.ApiClient(configuration) as api_client: # example passing only required values which don't have defaults set # and optional values try: - api_response = api_instance.submit_image_query(detector_id, human_review=human_review, image_query_id=image_query_id, inspection_id=inspection_id, metadata=metadata, patience_time=patience_time, want_async=want_async, body=body) + api_response = api_instance.submit_image_query(detector_id, confidence_threshold=confidence_threshold, human_review=human_review, image_query_id=image_query_id, inspection_id=inspection_id, metadata=metadata, patience_time=patience_time, want_async=want_async, body=body) pprint(api_response) except groundlight_openapi_client.ApiException as e: print("Exception when calling ImageQueriesApi->submit_image_query: %s\n" % e) @@ -312,6 +313,7 @@ with groundlight_openapi_client.ApiClient(configuration) as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **detector_id** | **str**| Choose a detector by its ID. | + **confidence_threshold** | **float**| The confidence threshold for the image query. | [optional] **human_review** | **str**| If set to `DEFAULT`, use the regular escalation logic (i.e., send the image query for human review if the ML model is not confident). If set to `ALWAYS`, always send the image query for human review even if the ML model is confident. If set to `NEVER`, never send the image query for human review even if the ML model is not confident. | [optional] **image_query_id** | **str**| The ID to assign to the created image query. | [optional] **inspection_id** | **str**| Associate the image query with an inspection. | [optional] diff --git a/generated/groundlight_openapi_client/api/image_queries_api.py b/generated/groundlight_openapi_client/api/image_queries_api.py index d9925f9d..cd8d0577 100644 --- a/generated/groundlight_openapi_client/api/image_queries_api.py +++ b/generated/groundlight_openapi_client/api/image_queries_api.py @@ -170,6 +170,7 @@ def __init__(self, api_client=None): params_map={ "all": [ "detector_id", + "confidence_threshold", "human_review", "image_query_id", "inspection_id", @@ -183,13 +184,21 @@ def __init__(self, api_client=None): ], "nullable": [], "enum": [], - "validation": [], + "validation": [ + "confidence_threshold", + ], }, root_map={ - "validations": {}, + "validations": { + ("confidence_threshold",): { + "inclusive_maximum": 1, + "inclusive_minimum": 0, + }, + }, "allowed_values": {}, "openapi_types": { "detector_id": (str,), + "confidence_threshold": (float,), "human_review": (str,), "image_query_id": (str,), "inspection_id": (str,), @@ -200,6 +209,7 @@ def __init__(self, api_client=None): }, "attribute_map": { "detector_id": "detector_id", + "confidence_threshold": "confidence_threshold", "human_review": "human_review", "image_query_id": "image_query_id", "inspection_id": "inspection_id", @@ -209,6 +219,7 @@ def __init__(self, api_client=None): }, "location_map": { "detector_id": "query", + "confidence_threshold": "query", "human_review": "query", "image_query_id": "query", "inspection_id": "query", @@ -421,6 +432,7 @@ def submit_image_query(self, detector_id, **kwargs): detector_id (str): Choose a detector by its ID. Keyword Args: + confidence_threshold (float): The confidence threshold for the image query.. [optional] human_review (str): If set to `DEFAULT`, use the regular escalation logic (i.e., send the image query for human review if the ML model is not confident). If set to `ALWAYS`, always send the image query for human review even if the ML model is confident. If set to `NEVER`, never send the image query for human review even if the ML model is not confident.. [optional] image_query_id (str): The ID to assign to the created image query.. [optional] inspection_id (str): Associate the image query with an inspection.. [optional] diff --git a/generated/groundlight_openapi_client/model/count_mode_configuration.py b/generated/groundlight_openapi_client/model/count_mode_configuration.py index 25e7539d..9c2d3be9 100644 --- a/generated/groundlight_openapi_client/model/count_mode_configuration.py +++ b/generated/groundlight_openapi_client/model/count_mode_configuration.py @@ -93,6 +93,7 @@ def openapi_types(): and the value is attribute type. """ return { + "class_name": (str,), # noqa: E501 "max_count": (int,), # noqa: E501 } @@ -101,6 +102,7 @@ def discriminator(): return None attribute_map = { + "class_name": "class_name", # noqa: E501 "max_count": "max_count", # noqa: E501 } @@ -110,9 +112,12 @@ def discriminator(): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 + def _from_openapi_data(cls, class_name, *args, **kwargs): # noqa: E501 """CountModeConfiguration - a model defined in OpenAPI + Args: + class_name (str): + Keyword Args: _check_type (bool): if True, values for parameters in openapi_types will be type checked and a TypeError will be @@ -173,6 +178,7 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + self.class_name = class_name for var_name, var_value in kwargs.items(): if ( var_name not in self.attribute_map @@ -195,9 +201,12 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 ]) @convert_js_args_to_python_args - def __init__(self, *args, **kwargs): # noqa: E501 + def __init__(self, class_name, *args, **kwargs): # noqa: E501 """CountModeConfiguration - a model defined in OpenAPI + Args: + class_name (str): + Keyword Args: _check_type (bool): if True, values for parameters in openapi_types will be type checked and a TypeError will be @@ -256,6 +265,7 @@ def __init__(self, *args, **kwargs): # noqa: E501 self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + self.class_name = class_name for var_name, var_value in kwargs.items(): if ( var_name not in self.attribute_map diff --git a/generated/groundlight_openapi_client/model/counting_result.py b/generated/groundlight_openapi_client/model/counting_result.py index 1bc61441..774cabce 100644 --- a/generated/groundlight_openapi_client/model/counting_result.py +++ b/generated/groundlight_openapi_client/model/counting_result.py @@ -64,6 +64,9 @@ class CountingResult(ModelNormal): } validations = { + ("count",): { + "inclusive_minimum": 0, + }, ("confidence",): { "inclusive_maximum": 1.0, "inclusive_minimum": 0.0, diff --git a/generated/model.py b/generated/model.py index a6de6439..dab8884e 100644 --- a/generated/model.py +++ b/generated/model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: public-api.yaml -# timestamp: 2024-12-05T21:27:07+00:00 +# timestamp: 2024-12-07T00:51:02+00:00 from __future__ import annotations @@ -200,7 +200,7 @@ class BinaryClassificationResult(BaseModel): class CountingResult(BaseModel): confidence: Optional[confloat(ge=0.0, le=1.0)] = None source: Optional[Source] = None - count: int + count: conint(ge=0) greater_than_max: Optional[bool] = None @@ -212,6 +212,7 @@ class MultiClassificationResult(BaseModel): class CountModeConfiguration(BaseModel): max_count: Optional[conint(ge=1, le=50)] = None + class_name: str class MultiClassModeConfiguration(BaseModel): diff --git a/pyproject.toml b/pyproject.toml index 69a5e792..8bdb11d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ packages = [ {include = "**/*.py", from = "src"}, ] readme = "README.md" -version = "0.20.0" +version = "0.21.0" [tool.poetry.dependencies] # For certifi, use ">=" instead of "^" since it upgrades its "major version" every year, not really following semver diff --git a/spec/public-api.yaml b/spec/public-api.yaml index b227293d..89f9f0c0 100644 --- a/spec/public-api.yaml +++ b/spec/public-api.yaml @@ -347,6 +347,14 @@ paths: --data-binary @path/to/filename.jpeg ``` parameters: + - in: query + name: confidence_threshold + schema: + type: number + format: float + minimum: 0 + maximum: 1 + description: The confidence threshold for the image query. - in: query name: detector_id schema: @@ -1367,8 +1375,7 @@ components: - ALGORITHM count: type: integer - minimum: null - maximum: null + minimum: 0 greater_than_max: type: boolean required: @@ -1400,7 +1407,10 @@ components: type: integer minimum: 1 maximum: 50 - required: [] + class_name: + type: string + required: + - class_name MultiClassModeConfiguration: type: object properties: @@ -1410,8 +1420,6 @@ components: type: string num_classes: type: integer - minimum: null - maximum: null required: - class_names ChannelEnum: diff --git a/src/groundlight/experimental_api.py b/src/groundlight/experimental_api.py index aac00fa5..d3d9721c 100644 --- a/src/groundlight/experimental_api.py +++ b/src/groundlight/experimental_api.py @@ -687,6 +687,7 @@ def create_counting_detector( # noqa: PLR0913 # pylint: disable=too-many-argume self, name: str, query: str, + class_name: str, *, max_count: Optional[int] = None, group_name: Optional[str] = None, @@ -706,6 +707,7 @@ def create_counting_detector( # noqa: PLR0913 # pylint: disable=too-many-argume detector = gl.create_counting_detector( name="people_counter", query="How many people are in the image?", + class_name="person", max_count=5, confidence_threshold=0.9, patience_time=30.0 @@ -718,6 +720,7 @@ def create_counting_detector( # noqa: PLR0913 # pylint: disable=too-many-argume :param name: A short, descriptive name for the detector. :param query: A question about the count of an object in the image. + :param class_name: The class name of the object to count. :param max_count: Maximum number of objects to count (default: 10) :param group_name: Optional name of a group to organize related detectors together. :param confidence_threshold: A value that sets the minimum confidence level required for the ML model's @@ -747,7 +750,7 @@ def create_counting_detector( # noqa: PLR0913 # pylint: disable=too-many-argume # TODO: pull the BE defined default if max_count is None: max_count = 10 - mode_config = CountModeConfiguration(max_count=max_count) + mode_config = CountModeConfiguration(max_count=max_count, class_name=class_name) detector_creation_input.mode_configuration = mode_config obj = self.detectors_api.create_detector(detector_creation_input, _request_timeout=DEFAULT_REQUEST_TIMEOUT) return Detector.parse_obj(obj.to_dict()) diff --git a/test/unit/test_experimental.py b/test/unit/test_experimental.py index 3ad0b5e1..b0dca6a2 100644 --- a/test/unit/test_experimental.py +++ b/test/unit/test_experimental.py @@ -100,7 +100,7 @@ def test_counting_detector(gl_experimental: ExperimentalApi): verify that we can create and submit to a counting detector """ name = f"Test {datetime.utcnow()}" - created_detector = gl_experimental.create_counting_detector(name, "How many dogs") + created_detector = gl_experimental.create_counting_detector(name, "How many dogs", "dog") assert created_detector is not None count_iq = gl_experimental.submit_image_query(created_detector, "test/assets/dog.jpeg") assert count_iq.result.count is not None