Skip to content

Commit 915c0d0

Browse files
blaise-muhirwaAuto-format Botsunildkumarmjvogelsong
authored
Switch Human Review Query Parameter from Boolean to String (#86)
* use human review query param as a string * add unit test * Automatically reformatting code * edit unit test * Automatically reformatting code * clean up test * updated wait times on tests such that they can pass server size valid… (#84) * updated wait times on tests such that they can pass server size validation. This will be improved once we separate client and service wait times * Automatically reformatting code * small update based on Tim's review * Automatically reformatting code --------- Co-authored-by: Auto-format Bot <[email protected]> * human review default to none * Automatically reformatting code * Update src/groundlight/client.py Co-authored-by: Michael Vogelsong <[email protected]> * address pr feedback --------- Co-authored-by: Auto-format Bot <[email protected]> Co-authored-by: Sunil Kumar <[email protected]> Co-authored-by: Michael Vogelsong <[email protected]>
1 parent 79df72f commit 915c0d0

File tree

6 files changed

+39
-16
lines changed

6 files changed

+39
-16
lines changed

generated/docs/ImageQueriesApi.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ with openapi_client.ApiClient(configuration) as api_client:
205205
# Create an instance of the API class
206206
api_instance = image_queries_api.ImageQueriesApi(api_client)
207207
detector_id = "detector_id_example" # str | Choose a detector by its ID.
208-
human_review = True # bool | Allow image queries to be marked for no human review. (optional)
208+
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)
209209
patience_time = 3.14 # float | How long to wait for a confident response. (optional)
210210
body = open('@path/to/image.jpeg', 'rb') # file_type | (optional)
211211

@@ -231,7 +231,7 @@ with openapi_client.ApiClient(configuration) as api_client:
231231
Name | Type | Description | Notes
232232
------------- | ------------- | ------------- | -------------
233233
**detector_id** | **str**| Choose a detector by its ID. |
234-
**human_review** | **bool**| Allow image queries to be marked for no human review. | [optional]
234+
**human_review** | **str**| If set to &#x60;DEFAULT&#x60;, use the regular escalation logic (i.e., send the image query for human review if the ML model is not confident). If set to &#x60;ALWAYS&#x60;, always send the image query for human review even if the ML model is confident. If set to &#x60;NEVER&#x60;, never send the image query for human review even if the ML model is not confident. | [optional]
235235
**patience_time** | **float**| How long to wait for a confident response. | [optional]
236236
**body** | **file_type**| | [optional]
237237

generated/model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# generated by datamodel-codegen:
22
# filename: public-api.yaml
3-
# timestamp: 2023-08-01T00:09:22+00:00
3+
# timestamp: 2023-08-09T20:46:11+00:00
44

55
from __future__ import annotations
66

generated/openapi_client/api/image_queries_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def __init__(self, api_client=None):
147147
"allowed_values": {},
148148
"openapi_types": {
149149
"detector_id": (str,),
150-
"human_review": (bool,),
150+
"human_review": (str,),
151151
"patience_time": (float,),
152152
"body": (file_type,),
153153
},
@@ -297,7 +297,7 @@ def submit_image_query(self, detector_id, **kwargs):
297297
detector_id (str): Choose a detector by its ID.
298298
299299
Keyword Args:
300-
human_review (bool): If set to `False` then unconfident ML predictions will not be escalated to human review. [optional, defaults `True`]
300+
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]
301301
patience_time (float): How long to wait for a confident response.. [optional]
302302
body (file_type): [optional]
303303
_return_http_data_only (bool): response data without head status

spec/public-api.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,11 @@ paths:
135135
- in: query
136136
name: human_review
137137
schema:
138-
type: boolean
139-
description: If set to `False` then unconfident ML predictions will not be escalated to human review. (Defaults `True`)
138+
type: string
139+
description: >
140+
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).
141+
If set to `ALWAYS`, always send the image query for human review even if the ML model is confident.
142+
If set to `NEVER`, never send the image query for human review even if the ML model is not confident.
140143
required: false
141144
- in: query
142145
name: patience_time

src/groundlight/client.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def submit_image_query(
170170
detector: Union[Detector, str],
171171
image: Union[str, bytes, Image.Image, BytesIO, BufferedReader, np.ndarray],
172172
wait: Optional[float] = None,
173-
human_review: Optional[bool] = True,
173+
human_review: Optional[str] = None,
174174
) -> ImageQuery:
175175
"""Evaluates an image with Groundlight.
176176
:param detector: the Detector object, or string id of a detector like `det_12345`
@@ -183,17 +183,27 @@ def submit_image_query(
183183
Any binary format must be JPEG-encoded already. Any pixel format will get
184184
converted to JPEG at high quality before sending to service.
185185
:param wait: How long to wait (in seconds) for a confident answer.
186-
:param human_review: If set to False, do not escalate for human review
186+
:param human_review: If `None` or `DEFAULT`, send the image query for human review
187+
only if the ML prediction is not confident.
188+
If set to `ALWAYS`, always send the image query for human review.
189+
If set to `NEVER`, never send the image query for human review.
187190
"""
188191
if wait is None:
189192
wait = self.DEFAULT_WAIT
190193
detector_id = detector.id if isinstance(detector, Detector) else detector
191194

192195
image_bytesio: ByteStreamWrapper = parse_supported_image_types(image)
193196

194-
raw_image_query = self.image_queries_api.submit_image_query(
195-
detector_id=detector_id, patience_time=wait, human_review=human_review, body=image_bytesio
196-
)
197+
params = {"detector_id": detector_id, "body": image_bytesio}
198+
if wait == 0:
199+
params["patience_time"] = self.DEFAULT_WAIT
200+
else:
201+
params["patience_time"] = wait
202+
203+
if human_review is not None:
204+
params["human_review"] = human_review
205+
206+
raw_image_query = self.image_queries_api.submit_image_query(**params)
197207
image_query = ImageQuery.parse_obj(raw_image_query.to_dict())
198208
if wait:
199209
threshold = self.get_detector(detector).confidence_threshold

test/integration/test_groundlight.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def is_valid_display_label(label: str) -> bool:
3535
def fixture_gl() -> Groundlight:
3636
"""Creates a Groundlight client object for testing."""
3737
_gl = Groundlight()
38-
_gl.DEFAULT_WAIT = 0.1
38+
_gl.DEFAULT_WAIT = 10
3939
return _gl
4040

4141

@@ -163,8 +163,7 @@ def test_get_detector_by_name(gl: Groundlight, detector: Detector):
163163

164164

165165
def test_submit_image_query_blocking(gl: Groundlight, detector: Detector):
166-
# Ask for a trivially small wait so it never has time to update, but uses the code path
167-
_image_query = gl.submit_image_query(detector=detector.id, image="test/assets/dog.jpeg", wait=2)
166+
_image_query = gl.submit_image_query(detector=detector.id, image="test/assets/dog.jpeg", wait=10)
168167
assert str(_image_query)
169168
assert isinstance(_image_query, ImageQuery)
170169
assert is_valid_display_result(_image_query.result)
@@ -173,7 +172,7 @@ def test_submit_image_query_blocking(gl: Groundlight, detector: Detector):
173172
def test_submit_image_query_returns_yes(gl: Groundlight):
174173
# We use the "never-review" pipeline to guarantee a confident "yes" answer.
175174
detector = gl.get_or_create_detector(name="Always a dog", query="Is there a dog?", pipeline_config="never-review")
176-
image_query = gl.submit_image_query(detector=detector, image="test/assets/dog.jpeg", wait=2)
175+
image_query = gl.submit_image_query(detector=detector, image="test/assets/dog.jpeg", wait=10)
177176
assert image_query.result.label == Label.YES
178177

179178

@@ -184,6 +183,17 @@ def test_submit_image_query_filename(gl: Groundlight, detector: Detector):
184183
assert is_valid_display_result(_image_query.result)
185184

186185

186+
def test_submit_image_query_with_human_review_param(gl: Groundlight, detector: Detector):
187+
# For now, this just tests that the image query is submitted successfully.
188+
# There should probably be a better way to check whether the image query was escalated for human review.
189+
190+
for human_review_value in ("DEFAULT", "ALWAYS", "NEVER"):
191+
_image_query = gl.submit_image_query(
192+
detector=detector.id, image="test/assets/dog.jpeg", human_review=human_review_value
193+
)
194+
assert is_valid_display_result(_image_query.result)
195+
196+
187197
def test_submit_image_query_jpeg_bytes(gl: Groundlight, detector: Detector):
188198
jpeg = open("test/assets/dog.jpeg", "rb").read()
189199
_image_query = gl.submit_image_query(detector=detector.id, image=jpeg)

0 commit comments

Comments
 (0)