diff --git a/Makefile b/Makefile index 816bfcdc..f9abe53f 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ generate: install-generator ## Generate the SDK from our public openapi spec -o ./generated \ --additional-properties=packageName=groundlight_openapi_client # strict-nullable makes nullable fields Optional in the generated Pydantic classes: https://github.com/koxudaxi/datamodel-code-generator/issues/327 - poetry run datamodel-codegen --input spec/public-api.yaml --output generated/model.py --strict-nullable --use-schema-description --output-model-type pydantic_v2.BaseModel --use-subclass-enum + poetry run datamodel-codegen --input spec/public-api.yaml --output generated/model.py --strict-nullable --use-schema-description --output-model-type pydantic_v2.BaseModel --use-subclass-enum --output-datetime-class datetime poetry run black . PYTEST=poetry run pytest -v diff --git a/generated/.openapi-generator/FILES b/generated/.openapi-generator/FILES index 4d99e803..d8fdc5e5 100644 --- a/generated/.openapi-generator/FILES +++ b/generated/.openapi-generator/FILES @@ -10,6 +10,7 @@ docs/BBoxGeometry.md docs/BBoxGeometryRequest.md docs/BinaryClassificationResult.md docs/BlankEnum.md +docs/BoundingBoxLabelEnum.md docs/BoundingBoxModeConfiguration.md docs/BoundingBoxResult.md docs/ChannelEnum.md @@ -96,6 +97,7 @@ groundlight_openapi_client/model/b_box_geometry.py groundlight_openapi_client/model/b_box_geometry_request.py groundlight_openapi_client/model/binary_classification_result.py groundlight_openapi_client/model/blank_enum.py +groundlight_openapi_client/model/bounding_box_label_enum.py groundlight_openapi_client/model/bounding_box_mode_configuration.py groundlight_openapi_client/model/bounding_box_result.py groundlight_openapi_client/model/channel_enum.py diff --git a/generated/README.md b/generated/README.md index acfcaec1..e21f5848 100644 --- a/generated/README.md +++ b/generated/README.md @@ -154,6 +154,7 @@ Class | Method | HTTP request | Description - [BBoxGeometryRequest](docs/BBoxGeometryRequest.md) - [BinaryClassificationResult](docs/BinaryClassificationResult.md) - [BlankEnum](docs/BlankEnum.md) + - [BoundingBoxLabelEnum](docs/BoundingBoxLabelEnum.md) - [BoundingBoxModeConfiguration](docs/BoundingBoxModeConfiguration.md) - [BoundingBoxResult](docs/BoundingBoxResult.md) - [ChannelEnum](docs/ChannelEnum.md) diff --git a/generated/docs/BoundingBoxLabelEnum.md b/generated/docs/BoundingBoxLabelEnum.md new file mode 100644 index 00000000..1cbd7e80 --- /dev/null +++ b/generated/docs/BoundingBoxLabelEnum.md @@ -0,0 +1,11 @@ +# BoundingBoxLabelEnum + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**value** | **str** | | must be one of ["NO_OBJECTS", "BOUNDING_BOX", "GREATER_THAN_MAX", "UNCLEAR", ] + +[[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/bounding_box_label_enum.py b/generated/groundlight_openapi_client/model/bounding_box_label_enum.py new file mode 100644 index 00000000..ed756ae4 --- /dev/null +++ b/generated/groundlight_openapi_client/model/bounding_box_label_enum.py @@ -0,0 +1,285 @@ +""" + Groundlight API + + Groundlight makes it simple to understand images. You can easily create computer vision detectors just by describing what you want to know using natural language. # noqa: E501 + + The version of the OpenAPI document: 0.18.2 + Contact: support@groundlight.ai + Generated by: https://openapi-generator.tech +""" + +import re # noqa: F401 +import sys # noqa: F401 + +from groundlight_openapi_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel, +) +from groundlight_openapi_client.exceptions import ApiAttributeError + + +class BoundingBoxLabelEnum(ModelSimple): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + ("value",): { + "NO_OBJECTS": "NO_OBJECTS", + "BOUNDING_BOX": "BOUNDING_BOX", + "GREATER_THAN_MAX": "GREATER_THAN_MAX", + "UNCLEAR": "UNCLEAR", + }, + } + + validations = {} + + additional_properties_type = None + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + "value": (str,), + } + + @cached_property + def discriminator(): + return None + + attribute_map = {} + + read_only_vars = set() + + _composed_schemas = None + + required_properties = set([ + "_data_store", + "_check_type", + "_spec_property_naming", + "_path_to_item", + "_configuration", + "_visited_composed_classes", + ]) + + @convert_js_args_to_python_args + def __init__(self, *args, **kwargs): + """BoundingBoxLabelEnum - a model defined in OpenAPI + + Note that value can be passed either in args or in kwargs, but not in both. + + Args: + args[0] (str):, must be one of ["NO_OBJECTS", "BOUNDING_BOX", "GREATER_THAN_MAX", "UNCLEAR", ] # noqa: E501 + + Keyword Args: + value (str):, must be one of ["NO_OBJECTS", "BOUNDING_BOX", "GREATER_THAN_MAX", "UNCLEAR", ] # 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. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + # required up here when default value is not given + _path_to_item = kwargs.pop("_path_to_item", ()) + + if "value" in kwargs: + value = kwargs.pop("value") + elif args: + args = list(args) + value = args.pop(0) + else: + raise ApiTypeError( + "value is required, but not passed in args or kwargs and doesn't have default", + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + _check_type = kwargs.pop("_check_type", True) + _spec_property_naming = kwargs.pop("_spec_property_naming", False) + _configuration = kwargs.pop("_configuration", None) + _visited_composed_classes = kwargs.pop("_visited_composed_classes", ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." + % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + self.value = value + if kwargs: + raise ApiTypeError( + "Invalid named arguments=%s passed to %s. Remove those invalid named arguments." + % ( + kwargs, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, *args, **kwargs): + """BoundingBoxLabelEnum - a model defined in OpenAPI + + Note that value can be passed either in args or in kwargs, but not in both. + + Args: + args[0] (str):, must be one of ["NO_OBJECTS", "BOUNDING_BOX", "GREATER_THAN_MAX", "UNCLEAR", ] # noqa: E501 + + Keyword Args: + value (str):, must be one of ["NO_OBJECTS", "BOUNDING_BOX", "GREATER_THAN_MAX", "UNCLEAR", ] # 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. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + # required up here when default value is not given + _path_to_item = kwargs.pop("_path_to_item", ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if "value" in kwargs: + value = kwargs.pop("value") + elif args: + args = list(args) + value = args.pop(0) + else: + raise ApiTypeError( + "value is required, but not passed in args or kwargs and doesn't have default", + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + _check_type = kwargs.pop("_check_type", True) + _spec_property_naming = kwargs.pop("_spec_property_naming", False) + _configuration = kwargs.pop("_configuration", None) + _visited_composed_classes = kwargs.pop("_visited_composed_classes", ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." + % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + self.value = value + if kwargs: + raise ApiTypeError( + "Invalid named arguments=%s passed to %s. Remove those invalid named arguments." + % ( + kwargs, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + return self diff --git a/generated/groundlight_openapi_client/models/__init__.py b/generated/groundlight_openapi_client/models/__init__.py index e9de218b..a7877c28 100644 --- a/generated/groundlight_openapi_client/models/__init__.py +++ b/generated/groundlight_openapi_client/models/__init__.py @@ -18,6 +18,7 @@ from groundlight_openapi_client.model.b_box_geometry_request import BBoxGeometryRequest from groundlight_openapi_client.model.binary_classification_result import BinaryClassificationResult from groundlight_openapi_client.model.blank_enum import BlankEnum +from groundlight_openapi_client.model.bounding_box_label_enum import BoundingBoxLabelEnum from groundlight_openapi_client.model.bounding_box_mode_configuration import BoundingBoxModeConfiguration from groundlight_openapi_client.model.bounding_box_result import BoundingBoxResult from groundlight_openapi_client.model.channel_enum import ChannelEnum diff --git a/generated/model.py b/generated/model.py index 1de65384..beb0d978 100644 --- a/generated/model.py +++ b/generated/model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: public-api.yaml -# timestamp: 2025-08-28T18:43:04+00:00 +# timestamp: 2025-10-20T17:36:39+00:00 from __future__ import annotations @@ -324,6 +324,13 @@ class VerbEnum(str, Enum): NO_QUERIES = "NO_QUERIES" +class BoundingBoxLabelEnum(str, Enum): + NO_OBJECTS = "NO_OBJECTS" + BOUNDING_BOX = "BOUNDING_BOX" + GREATER_THAN_MAX = "GREATER_THAN_MAX" + UNCLEAR = "UNCLEAR" + + class Source(str, Enum): STILL_PROCESSING = "STILL_PROCESSING" CLOUD = "CLOUD" @@ -479,16 +486,16 @@ class LabelValueRequest(BaseModel): class PaginatedDetectorList(BaseModel): - count: int = Field(..., example=123) - next: Optional[AnyUrl] = Field(None, example="http://api.example.org/accounts/?page=4") - previous: Optional[AnyUrl] = Field(None, example="http://api.example.org/accounts/?page=2") + count: int = Field(..., examples=[123]) + next: Optional[AnyUrl] = Field(None, examples=["http://api.example.org/accounts/?page=4"]) + previous: Optional[AnyUrl] = Field(None, examples=["http://api.example.org/accounts/?page=2"]) results: List[Detector] class PaginatedImageQueryList(BaseModel): - count: int = Field(..., example=123) - next: Optional[AnyUrl] = Field(None, example="http://api.example.org/accounts/?page=4") - previous: Optional[AnyUrl] = Field(None, example="http://api.example.org/accounts/?page=2") + count: int = Field(..., examples=[123]) + next: Optional[AnyUrl] = Field(None, examples=["http://api.example.org/accounts/?page=4"]) + previous: Optional[AnyUrl] = Field(None, examples=["http://api.example.org/accounts/?page=2"]) results: List[ImageQuery] @@ -545,7 +552,7 @@ class RuleRequest(BaseModel): class PaginatedRuleList(BaseModel): - count: int = Field(..., example=123) - next: Optional[AnyUrl] = Field(None, example="http://api.example.org/accounts/?page=4") - previous: Optional[AnyUrl] = Field(None, example="http://api.example.org/accounts/?page=2") + count: int = Field(..., examples=[123]) + next: Optional[AnyUrl] = Field(None, examples=["http://api.example.org/accounts/?page=4"]) + previous: Optional[AnyUrl] = Field(None, examples=["http://api.example.org/accounts/?page=2"]) results: List[Rule] diff --git a/generated/test/test_bounding_box_label_enum.py b/generated/test/test_bounding_box_label_enum.py new file mode 100644 index 00000000..2d15f47d --- /dev/null +++ b/generated/test/test_bounding_box_label_enum.py @@ -0,0 +1,35 @@ +""" + Groundlight API + + Groundlight makes it simple to understand images. You can easily create computer vision detectors just by describing what you want to know using natural language. # noqa: E501 + + The version of the OpenAPI document: 0.18.2 + Contact: support@groundlight.ai + Generated by: https://openapi-generator.tech +""" + +import sys +import unittest + +import groundlight_openapi_client +from groundlight_openapi_client.model.bounding_box_label_enum import BoundingBoxLabelEnum + + +class TestBoundingBoxLabelEnum(unittest.TestCase): + """BoundingBoxLabelEnum unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testBoundingBoxLabelEnum(self): + """Test BoundingBoxLabelEnum""" + # FIXME: construct object with mandatory attributes with example values + # model = BoundingBoxLabelEnum() # noqa: E501 + pass + + +if __name__ == "__main__": + unittest.main() diff --git a/pyproject.toml b/pyproject.toml index 3c6c5a57..a78bc032 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ packages = [ {include = "**/*.py", from = "src"}, ] readme = "README.md" -version = "0.23.2" +version = "0.23.3" [tool.poetry.dependencies] # For certifi, use ">=" instead of "^" since it upgrades its "major version" every year, not really following semver @@ -24,7 +24,7 @@ typer = "^0.15.4" urllib3 = "^2.5.0" [tool.poetry.group.dev.dependencies] -datamodel-code-generator = "^0.22.1" +datamodel-code-generator = "^0.35.0" pre-commit = "^2.0.0" pytest = "^7.0.1" pytest-cov = "^3.0.0" diff --git a/spec/public-api.yaml b/spec/public-api.yaml index 197e1fac..d3e8360c 100644 --- a/spec/public-api.yaml +++ b/spec/public-api.yaml @@ -1859,6 +1859,13 @@ components: - CHANGED_TO - NO_CHANGE - NO_QUERIES + BoundingBoxLabelEnum: + type: string + enum: + - NO_OBJECTS + - BOUNDING_BOX + - GREATER_THAN_MAX + - UNCLEAR Source: type: string enum: