Skip to content

Commit

Permalink
added ask_async to submit_image_query
Browse files Browse the repository at this point in the history
  • Loading branch information
sunildkumar committed Oct 9, 2023
1 parent ec65a47 commit 98307c1
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 15 deletions.
14 changes: 11 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
"editor.codeActionsOnSave": {
"source.organizeImports": true
},
"python.analysis.extraPaths": ["./generated"],
"python.formatting.provider": "black"
}
"python.analysis.extraPaths": [
"./generated"
],
"python.formatting.provider": "black",
"ruff.importStrategy": "fromEnvironment",
"ruff.fixAll": true,
"ruff.organizeImports": false,
"ruff.path": [
"/.venv/bin/ruff"
],
}
2 changes: 1 addition & 1 deletion generated/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class ImageQuery(BaseModel):
query: str = Field(..., description="A question about the image.")
detector_id: str = Field(..., description="Which detector was used on this image query?")
result_type: ResultTypeEnum = Field(..., description="What type of result are we returning?")
result: ClassificationResult
result: ClassificationResult | None


class PaginatedDetectorList(BaseModel):
Expand Down
42 changes: 31 additions & 11 deletions src/groundlight/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@
from io import BufferedReader, BytesIO
from typing import Optional, Union

from model import Detector, ImageQuery, PaginatedDetectorList, PaginatedImageQueryList
from model import (Detector, ImageQuery, PaginatedDetectorList,
PaginatedImageQueryList)
from openapi_client import Configuration
from openapi_client.api.detectors_api import DetectorsApi
from openapi_client.api.image_queries_api import ImageQueriesApi
from openapi_client.model.detector_creation_input import DetectorCreationInput

from groundlight.binary_labels import Label, convert_display_label_to_internal, convert_internal_label_to_display
from groundlight.binary_labels import (Label,
convert_display_label_to_internal,
convert_internal_label_to_display)
from groundlight.config import API_TOKEN_VARIABLE_NAME, API_TOKEN_WEB_URL
from groundlight.images import ByteStreamWrapper, parse_supported_image_types
from groundlight.internalapi import (
GroundlightApiClient,
NotFoundError,
iq_is_confident,
sanitize_endpoint_url,
)
from groundlight.internalapi import (GroundlightApiClient, NotFoundError,
iq_is_confident, sanitize_endpoint_url)
from groundlight.optional_imports import Image, np

logger = logging.getLogger("groundlight.sdk")
Expand Down Expand Up @@ -76,10 +75,19 @@ def __init__(self, endpoint: Optional[str] = None, api_token: Optional[str] = No
self.detectors_api = DetectorsApi(self.api_client)
self.image_queries_api = ImageQueriesApi(self.api_client)

def _fixup_image_query(self, iq: ImageQuery) -> ImageQuery: # pylint: disable=no-self-use
"""Process the wire-format image query to make it more usable."""
def _fixup_image_query(self, iq: ImageQuery, want_async:bool=False) -> ImageQuery: # pylint: disable=no-self-use
"""
Post process an image query prior to returning it to the user.
:param iq: The image query to fix up.
:param want_async: post processing for want_async=True option in submit_image_query
"""
# Note: This might go away once we clean up the mapping logic server-side.
iq.result.label = convert_internal_label_to_display(iq, iq.result.label)
if want_async:
# If want_async is True, the result returned to the user should be None because the client intentionally
# wants to query for the result later. Any result returned by the server is NOT representative of the
# query's actual result.
iq.result = None
return iq

def get_detector(self, id: Union[str, Detector]) -> Detector: # pylint: disable=redefined-builtin
Expand Down Expand Up @@ -178,6 +186,7 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments
image: Union[str, bytes, Image.Image, BytesIO, BufferedReader, np.ndarray],
wait: Optional[float] = None,
human_review: Optional[str] = None,
want_async: bool = False,
inspection_id: Optional[str] = None,
) -> ImageQuery:
"""Evaluates an image with Groundlight.
Expand All @@ -195,6 +204,8 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments
only if the ML prediction is not confident.
If set to `ALWAYS`, always send the image query for human review.
If set to `NEVER`, never send the image query for human review.
:param want_async: If True, the client will return as soon as the image query is submitted and will not wait for
an ML/human prediction. The returned `ImageQuery` will have a `result` of None. Incompatible with `wait`.
:param inspection_id: Most users will omit this. For accounts with Inspection Reports enabled,
this is the ID of the inspection to associate with the image query.
"""
Expand All @@ -213,6 +224,14 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments

if human_review is not None:
params["human_review"] = human_review

if want_async is True:
# If want_async is True, we don't want to wait for a result. As a result using both wait and want_async makes
# no sense.
if wait is not None:
raise ValueError("wait must be None if want_async is True as the two are incompatible. Please set wait"
" to None to use want_async.")
params["want_async"] = want_async

# If no inspection_id is provided, we submit the image query using image_queries_api (autogenerated via OpenAPI)
# However, our autogenerated code does not currently support inspection_id, so if an inspection_id was
Expand All @@ -228,7 +247,8 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments
if wait:
threshold = self.get_detector(detector).confidence_threshold
image_query = self.wait_for_confident_result(image_query, confidence_threshold=threshold, timeout_sec=wait)
return self._fixup_image_query(image_query)

return self._fixup_image_query(image_query, want_async=want_async)

def wait_for_confident_result(
self,
Expand Down

0 comments on commit 98307c1

Please sign in to comment.