Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions generated/docs/CountModeConfiguration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down
4 changes: 3 additions & 1 deletion generated/docs/ImageQueriesApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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]
Expand Down
16 changes: 14 additions & 2 deletions generated/groundlight_openapi_client/api/image_queries_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ def __init__(self, api_client=None):
params_map={
"all": [
"detector_id",
"confidence_threshold",
"human_review",
"image_query_id",
"inspection_id",
Expand All @@ -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,),
Expand All @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def openapi_types():
and the value is attribute type.
"""
return {
"class_name": (str,), # noqa: E501
"max_count": (int,), # noqa: E501
}

Expand All @@ -101,6 +102,7 @@ def discriminator():
return None

attribute_map = {
"class_name": "class_name", # noqa: E501
"max_count": "max_count", # noqa: E501
}

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions generated/groundlight_openapi_client/model/counting_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class CountingResult(ModelNormal):
}

validations = {
("count",): {
"inclusive_minimum": 0,
},
("confidence",): {
"inclusive_maximum": 1.0,
"inclusive_minimum": 0.0,
Expand Down
5 changes: 3 additions & 2 deletions generated/model.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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


Expand All @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 13 additions & 5 deletions spec/public-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -1367,8 +1375,7 @@ components:
- ALGORITHM
count:
type: integer
minimum: null
maximum: null
minimum: 0
greater_than_max:
type: boolean
required:
Expand Down Expand Up @@ -1400,7 +1407,10 @@ components:
type: integer
minimum: 1
maximum: 50
required: []
class_name:
type: string
required:
- class_name
MultiClassModeConfiguration:
type: object
properties:
Expand All @@ -1410,8 +1420,6 @@ components:
type: string
num_classes:
type: integer
minimum: null
maximum: null
required:
- class_names
ChannelEnum:
Expand Down
5 changes: 4 additions & 1 deletion src/groundlight/experimental_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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())
Expand Down
2 changes: 1 addition & 1 deletion test/unit/test_experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading