diff --git a/src/groundlight/client.py b/src/groundlight/client.py index a603edd3..09308439 100644 --- a/src/groundlight/client.py +++ b/src/groundlight/client.py @@ -637,6 +637,7 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments, t inspection_id: Optional[str] = None, metadata: Union[dict, str, None] = None, image_query_id: Optional[str] = None, + request_timeout: Optional[float] = None, ) -> ImageQuery: """ Evaluates an image with Groundlight. This is the core method for getting predictions about images. @@ -718,6 +719,8 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments, t :param image_query_id: The ID for the image query. This is to enable specific functionality and is not intended for general external use. If not set, a random ID will be generated. + :param request_timeout: The total request timeout for the image query submission API request. Most users will + not need to modify this. If not set, the default value will be used. :return: ImageQuery with query details and result (if wait > 0) :raises ValueError: If wait > 0 when want_async=True @@ -731,7 +734,11 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments, t image_bytesio: ByteStreamWrapper = parse_supported_image_types(image) - params = {"detector_id": detector_id, "body": image_bytesio, "_request_timeout": DEFAULT_REQUEST_TIMEOUT} + params = { + "detector_id": detector_id, + "body": image_bytesio, + "_request_timeout": request_timeout if request_timeout is not None else DEFAULT_REQUEST_TIMEOUT, + } if patience_time is not None: params["patience_time"] = patience_time diff --git a/test/integration/test_groundlight.py b/test/integration/test_groundlight.py index c68e47ea..40c74f12 100644 --- a/test/integration/test_groundlight.py +++ b/test/integration/test_groundlight.py @@ -26,6 +26,7 @@ PaginatedDetectorList, PaginatedImageQueryList, ) +from urllib3.exceptions import ReadTimeoutError DEFAULT_CONFIDENCE_THRESHOLD = 0.9 IQ_IMPROVEMENT_THRESHOLD = 0.75 @@ -348,6 +349,17 @@ def test_submit_image_query_with_human_review_param(gl: Groundlight, detector: D assert is_valid_display_result(_image_query.result) +def test_submit_image_query_with_low_request_timeout(gl: Groundlight, detector: Detector, image: str): + """ + Test that submit_image_query respects the request_timeout parameter and raises a ReadTimeoutError when timeout is + exceeded. + """ + with pytest.raises(ReadTimeoutError): + # Setting a very low request_timeout value should result in a timeout. + # NOTE: request_timeout=0 seems to have special behavior that does not result in a timeout. + gl.submit_image_query(detector=detector, image=image, human_review="NEVER", request_timeout=1e-8) + + @pytest.mark.skip_for_edge_endpoint(reason="The edge-endpoint does not support passing detector metadata.") def test_create_detector_with_metadata(gl: Groundlight): name = f"Test {datetime.utcnow()}" # Need a unique name