From 3e377f54b3e76e09e8d7d97ce00d9978287a521a Mon Sep 17 00:00:00 2001 From: Brandon <132288221+brandon-groundlight@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:26:35 -0700 Subject: [PATCH] Ocr support (#255) * Prioritizing OCR release, this api spec doesn't match any BE version. It skips the Actions update but contains the update for OCR * running the generator * Adding test with new functionality * Automatically reformatting code --------- Co-authored-by: Auto-format Bot --- generated/.openapi-generator/FILES | 1 - generated/docs/ImageQuery.md | 1 + generated/docs/LabelValue.md | 3 ++- generated/docs/ResultTypeEnum.md | 2 +- .../model/image_query.py | 9 +++++++++ .../model/label_value.py | 12 ++++++++++-- .../model/result_type_enum.py | 9 +++++---- generated/model.py | 9 +++++++-- package-lock.json | 8 ++++---- package.json | 4 ++-- spec/public-api.yaml | 15 ++++++++++++++- test/integration/test_groundlight.py | 9 +++++++++ 12 files changed, 64 insertions(+), 18 deletions(-) diff --git a/generated/.openapi-generator/FILES b/generated/.openapi-generator/FILES index b50ee923..1258ead7 100644 --- a/generated/.openapi-generator/FILES +++ b/generated/.openapi-generator/FILES @@ -104,5 +104,4 @@ setup.cfg setup.py test-requirements.txt test/__init__.py -test/test_detector_reset_api.py tox.ini diff --git a/generated/docs/ImageQuery.md b/generated/docs/ImageQuery.md index e75a620b..2d3d6c48 100644 --- a/generated/docs/ImageQuery.md +++ b/generated/docs/ImageQuery.md @@ -16,6 +16,7 @@ Name | Type | Description | Notes **patience_time** | **float** | How long to wait for a confident response. | [readonly] **confidence_threshold** | **float** | Min confidence needed to accept the response of the image query. | [readonly] **rois** | [**[ROI], none_type**](ROI.md) | An array of regions of interest (bounding boxes) collected on image | [readonly] +**text** | **str, none_type** | A text field on image query. | [readonly] **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] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/generated/docs/LabelValue.md b/generated/docs/LabelValue.md index a96d9ab6..acbb0e6f 100644 --- a/generated/docs/LabelValue.md +++ b/generated/docs/LabelValue.md @@ -5,11 +5,12 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **confidence** | **float, none_type** | | [readonly] -**class_name** | **str, none_type** | A human-readable class name for this label (e.g. YES/NO) | [readonly] +**class_name** | **str, none_type** | Return a human-readable class name for this label (e.g. YES/NO) | [readonly] **annotations_requested** | **[bool, date, datetime, dict, float, int, list, str, none_type]** | | [readonly] **created_at** | **datetime** | | [readonly] **detector_id** | **int, none_type** | | [readonly] **source** | **bool, date, datetime, dict, float, int, list, str, none_type** | | [readonly] +**text** | **str, none_type** | Text annotations | [readonly] **rois** | [**[ROI], none_type**](ROI.md) | | [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/ResultTypeEnum.md b/generated/docs/ResultTypeEnum.md index d5292681..352f7694 100644 --- a/generated/docs/ResultTypeEnum.md +++ b/generated/docs/ResultTypeEnum.md @@ -4,7 +4,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**value** | **str** | | must be one of ["binary_classification", "counting", ] +**value** | **str** | | must be one of ["binary_classification", "counting", "multi_classification", ] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/generated/groundlight_openapi_client/model/image_query.py b/generated/groundlight_openapi_client/model/image_query.py index aa6a5a1b..70cd6666 100644 --- a/generated/groundlight_openapi_client/model/image_query.py +++ b/generated/groundlight_openapi_client/model/image_query.py @@ -151,6 +151,10 @@ def openapi_types(): [ROI], none_type, ), # noqa: E501 + "text": ( + str, + none_type, + ), # noqa: E501 } @cached_property @@ -169,6 +173,7 @@ def discriminator(): "patience_time": "patience_time", # noqa: E501 "confidence_threshold": "confidence_threshold", # noqa: E501 "rois": "rois", # noqa: E501 + "text": "text", # noqa: E501 } read_only_vars = { @@ -183,6 +188,7 @@ def discriminator(): "patience_time", # noqa: E501 "confidence_threshold", # noqa: E501 "rois", # noqa: E501 + "text", # noqa: E501 } _composed_schemas = {} @@ -202,6 +208,7 @@ def _from_openapi_data( patience_time, confidence_threshold, rois, + text, *args, **kwargs, ): # noqa: E501 @@ -219,6 +226,7 @@ def _from_openapi_data( patience_time (float): How long to wait for a confident response. confidence_threshold (float): Min confidence needed to accept the response of the image query. rois ([ROI], none_type): An array of regions of interest (bounding boxes) collected on image + text (str, none_type): A text field on image query. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -290,6 +298,7 @@ def _from_openapi_data( self.patience_time = patience_time self.confidence_threshold = confidence_threshold self.rois = rois + self.text = text for var_name, var_value in kwargs.items(): if ( var_name not in self.attribute_map diff --git a/generated/groundlight_openapi_client/model/label_value.py b/generated/groundlight_openapi_client/model/label_value.py index b6ac9148..1aaf7381 100644 --- a/generated/groundlight_openapi_client/model/label_value.py +++ b/generated/groundlight_openapi_client/model/label_value.py @@ -125,6 +125,10 @@ def openapi_types(): str, none_type, ), # noqa: E501 + "text": ( + str, + none_type, + ), # noqa: E501 "rois": ( [ROI], none_type, @@ -142,6 +146,7 @@ def discriminator(): "created_at": "created_at", # noqa: E501 "detector_id": "detector_id", # noqa: E501 "source": "source", # noqa: E501 + "text": "text", # noqa: E501 "rois": "rois", # noqa: E501 } @@ -152,6 +157,7 @@ def discriminator(): "created_at", # noqa: E501 "detector_id", # noqa: E501 "source", # noqa: E501 + "text", # noqa: E501 } _composed_schemas = {} @@ -159,17 +165,18 @@ def discriminator(): @classmethod @convert_js_args_to_python_args def _from_openapi_data( - cls, confidence, class_name, annotations_requested, created_at, detector_id, source, *args, **kwargs + cls, confidence, class_name, annotations_requested, created_at, detector_id, source, text, *args, **kwargs ): # noqa: E501 """LabelValue - a model defined in OpenAPI Args: confidence (float, none_type): - class_name (str, none_type): A human-readable class name for this label (e.g. YES/NO) + class_name (str, none_type): Return a human-readable class name for this label (e.g. YES/NO) annotations_requested ([bool, date, datetime, dict, float, int, list, str, none_type]): created_at (datetime): detector_id (int, none_type): source (bool, date, datetime, dict, float, int, list, str, none_type): + text (str, none_type): Text annotations Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -237,6 +244,7 @@ def _from_openapi_data( self.created_at = created_at self.detector_id = detector_id self.source = source + self.text = text for var_name, var_value in kwargs.items(): if ( var_name not in self.attribute_map diff --git a/generated/groundlight_openapi_client/model/result_type_enum.py b/generated/groundlight_openapi_client/model/result_type_enum.py index ea4702e4..8441a6c6 100644 --- a/generated/groundlight_openapi_client/model/result_type_enum.py +++ b/generated/groundlight_openapi_client/model/result_type_enum.py @@ -53,6 +53,7 @@ class ResultTypeEnum(ModelSimple): ("value",): { "BINARY_CLASSIFICATION": "binary_classification", "COUNTING": "counting", + "MULTI_CLASSIFICATION": "multi_classification", }, } @@ -102,10 +103,10 @@ def __init__(self, *args, **kwargs): Note that value can be passed either in args or in kwargs, but not in both. Args: - args[0] (str):, must be one of ["binary_classification", "counting", ] # noqa: E501 + args[0] (str):, must be one of ["binary_classification", "counting", "multi_classification", ] # noqa: E501 Keyword Args: - value (str):, must be one of ["binary_classification", "counting", ] # noqa: E501 + value (str):, must be one of ["binary_classification", "counting", "multi_classification", ] # noqa: E501 _check_type (bool): if True, values for parameters in openapi_types will be type checked and a TypeError will be raised if the wrong type is input. @@ -194,10 +195,10 @@ def _from_openapi_data(cls, *args, **kwargs): Note that value can be passed either in args or in kwargs, but not in both. Args: - args[0] (str):, must be one of ["binary_classification", "counting", ] # noqa: E501 + args[0] (str):, must be one of ["binary_classification", "counting", "multi_classification", ] # noqa: E501 Keyword Args: - value (str):, must be one of ["binary_classification", "counting", ] # noqa: E501 + value (str):, must be one of ["binary_classification", "counting", "multi_classification", ] # noqa: E501 _check_type (bool): if True, values for parameters in openapi_types will be type checked and a TypeError will be raised if the wrong type is input. diff --git a/generated/model.py b/generated/model.py index fee8fe3c..c63cfff5 100644 --- a/generated/model.py +++ b/generated/model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: public-api.yaml -# timestamp: 2024-08-26T21:12:31+00:00 +# timestamp: 2024-09-25T21:50:15+00:00 from __future__ import annotations @@ -110,6 +110,7 @@ class ROIRequest(BaseModel): class ResultTypeEnum(Enum): binary_classification = "binary_classification" counting = "counting" + multi_classification = "multi_classification" class SnoozeTimeUnitEnum(Enum): @@ -290,16 +291,20 @@ class ImageQuery(BaseModel): rois: Optional[List[ROI]] = Field( ..., description="An array of regions of interest (bounding boxes) collected on image" ) + text: Optional[str] = Field(..., description="A text field on image query.") class LabelValue(BaseModel): confidence: Optional[float] = Field(...) - class_name: Optional[str] = Field(..., description="A human-readable class name for this label (e.g. YES/NO)") + class_name: Optional[str] = Field( + ..., description="Return a human-readable class name for this label (e.g. YES/NO)" + ) rois: Optional[List[ROI]] = None annotations_requested: List[AnnotationsRequestedEnum] created_at: datetime detector_id: Optional[int] = Field(...) source: SourceEnum + text: Optional[str] = Field(..., description="Text annotations") class LabelValueRequest(BaseModel): diff --git a/package-lock.json b/package-lock.json index 36adb0f7..7d130a8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "name": "groundlight-sdk-generator", "dependencies": { "@openapitools/openapi-generator-cli": "^2.9.0", - "rehype-katex": "^7.0.0", + "rehype-katex": "^7.0.1", "remark-math": "^6.0.0" } }, @@ -1621,9 +1621,9 @@ "license": "Apache-2.0" }, "node_modules/rehype-katex": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz", - "integrity": "sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", "dependencies": { "@types/hast": "^3.0.0", "@types/katex": "^0.16.0", diff --git a/package.json b/package.json index c279bd3e..baebe0b9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "groundlight-sdk-generator", "dependencies": { "@openapitools/openapi-generator-cli": "^2.9.0", - "rehype-katex": "^7.0.0", + "rehype-katex": "^7.0.1", "remark-math": "^6.0.0" } -} \ No newline at end of file +} diff --git a/spec/public-api.yaml b/spec/public-api.yaml index 1db48358..53febc53 100644 --- a/spec/public-api.yaml +++ b/spec/public-api.yaml @@ -925,6 +925,11 @@ components: nullable: true description: An array of regions of interest (bounding boxes) collected on image + text: + type: string + nullable: true + readOnly: true + description: A text field on image query. required: - confidence_threshold - created_at @@ -936,6 +941,7 @@ components: - result - result_type - rois + - text - type x-internal: true ImageQueryTypeEnum: @@ -953,7 +959,7 @@ components: class_name: type: string nullable: true - description: A human-readable class name for this label (e.g. YES/NO) + description: Return a human-readable class name for this label (e.g. YES/NO) readOnly: true rois: type: array @@ -983,6 +989,11 @@ components: allOf: - $ref: '#/components/schemas/SourceEnum' readOnly: true + text: + type: string + readOnly: true + nullable: true + description: Text annotations required: - annotations_requested - class_name @@ -990,6 +1001,7 @@ components: - created_at - detector_id - source + - text LabelValueRequest: type: object properties: @@ -1145,6 +1157,7 @@ components: enum: - binary_classification - counting + - multi_classification type: string Rule: type: object diff --git a/test/integration/test_groundlight.py b/test/integration/test_groundlight.py index c4c87d14..8240b607 100644 --- a/test/integration/test_groundlight.py +++ b/test/integration/test_groundlight.py @@ -297,6 +297,15 @@ def test_submit_image_query_returns_yes(gl: Groundlight): assert image_query.result.label == Label.YES +def test_submit_image_query_returns_text(gl: Groundlight): + # We use the "never-review" pipeline to guarantee a confident "yes" answer. + detector = gl.get_or_create_detector( + name="Always same text", query="Is there a dog?", pipeline_config="constant-text" + ) + image_query = gl.submit_image_query(detector=detector, image="test/assets/dog.jpeg", wait=10, human_review="NEVER") + assert isinstance(image_query.text, str) + + def test_submit_image_query_filename(gl: Groundlight, detector: Detector): _image_query = gl.submit_image_query(detector=detector.id, image="test/assets/dog.jpeg", human_review="NEVER") assert str(_image_query)