diff --git a/.vscode/settings.json b/.vscode/settings.json index da8bb988..2fa0c950 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,17 +3,6 @@ "editor.codeActionsOnSave": { "source.organizeImports": true }, - "editor.rulers": [ - 100, - 120 - ], - "python.analysis.extraPaths": [ - "./generated" - ], - "python.formatting.provider": "black", - "[python]": { - "editor.codeActionsOnSave": { - "source.organizeImports": false - } - } -} \ No newline at end of file + "python.analysis.extraPaths": ["./generated"], + "python.formatting.provider": "black" +} diff --git a/generated/docs/ImageQueriesApi.md b/generated/docs/ImageQueriesApi.md index 6426adf8..248933f8 100644 --- a/generated/docs/ImageQueriesApi.md +++ b/generated/docs/ImageQueriesApi.md @@ -207,7 +207,6 @@ with openapi_client.ApiClient(configuration) as api_client: detector_id = "detector_id_example" # str | Choose a detector by its ID. 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) patience_time = 3.14 # float | How long to wait for a confident response. (optional) - want_async = "want_async_example" # str | If \"true\" then submitting an image query returns immediately without a result. The result will be computed asynchronously and can be retrieved later. (optional) body = open('@path/to/image.jpeg', 'rb') # file_type | (optional) # example passing only required values which don't have defaults set @@ -220,7 +219,7 @@ with openapi_client.ApiClient(configuration) as api_client: # example passing only required values which don't have defaults set # and optional values try: - api_response = api_instance.submit_image_query(detector_id, human_review=human_review, patience_time=patience_time, want_async=want_async, body=body) + api_response = api_instance.submit_image_query(detector_id, human_review=human_review, patience_time=patience_time, body=body) pprint(api_response) except openapi_client.ApiException as e: print("Exception when calling ImageQueriesApi->submit_image_query: %s\n" % e) @@ -234,7 +233,6 @@ Name | Type | Description | Notes **detector_id** | **str**| Choose a detector by its ID. | **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] **patience_time** | **float**| How long to wait for a confident response. | [optional] - **want_async** | **str**| If \"true\" then submitting an image query returns immediately without a result. The result will be computed asynchronously and can be retrieved later. | [optional] **body** | **file_type**| | [optional] ### Return type diff --git a/generated/docs/ImageQuery.md b/generated/docs/ImageQuery.md index 759118e5..98d125b2 100644 --- a/generated/docs/ImageQuery.md +++ b/generated/docs/ImageQuery.md @@ -11,7 +11,7 @@ Name | Type | Description | Notes **query** | **str** | A question about the image. | [readonly] **detector_id** | **str** | Which detector was used on this image query? | [readonly] **result_type** | **bool, date, datetime, dict, float, int, list, str, none_type** | What type of result are we returning? | [readonly] -**result** | **bool, date, datetime, dict, float, int, list, str, none_type** | | [optional] [readonly] +**result** | **bool, date, datetime, dict, float, int, list, str, none_type** | | [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/model.py b/generated/model.py index 6b62b9ae..dea486ca 100644 --- a/generated/model.py +++ b/generated/model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: public-api.yaml -# timestamp: 2023-10-16T23:29:00+00:00 +# timestamp: 2023-08-09T20:46:11+00:00 from __future__ import annotations @@ -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: Optional[ClassificationResult] = None + result: ClassificationResult class PaginatedDetectorList(BaseModel): diff --git a/generated/openapi_client/api/image_queries_api.py b/generated/openapi_client/api/image_queries_api.py index eb2ff05b..dd760ba8 100644 --- a/generated/openapi_client/api/image_queries_api.py +++ b/generated/openapi_client/api/image_queries_api.py @@ -133,7 +133,6 @@ def __init__(self, api_client=None): "detector_id", "human_review", "patience_time", - "want_async", "body", ], "required": [ @@ -150,20 +149,17 @@ def __init__(self, api_client=None): "detector_id": (str,), "human_review": (str,), "patience_time": (float,), - "want_async": (str,), "body": (file_type,), }, "attribute_map": { "detector_id": "detector_id", "human_review": "human_review", "patience_time": "patience_time", - "want_async": "want_async", }, "location_map": { "detector_id": "query", "human_review": "query", "patience_time": "query", - "want_async": "query", "body": "body", }, "collection_format_map": {}, @@ -303,7 +299,6 @@ def submit_image_query(self, detector_id, **kwargs): Keyword Args: 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] patience_time (float): How long to wait for a confident response.. [optional] - want_async (str): If \"true\" then submitting an image query returns immediately without a result. The result will be computed asynchronously and can be retrieved later.. [optional] body (file_type): [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. diff --git a/generated/openapi_client/model/image_query.py b/generated/openapi_client/model/image_query.py index b1d5deec..0100e22b 100644 --- a/generated/openapi_client/model/image_query.py +++ b/generated/openapi_client/model/image_query.py @@ -168,7 +168,9 @@ def discriminator(): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, id, type, created_at, query, detector_id, result_type, *args, **kwargs): # noqa: E501 + def _from_openapi_data( + cls, id, type, created_at, query, detector_id, result_type, result, *args, **kwargs + ): # noqa: E501 """ImageQuery - a model defined in OpenAPI Args: @@ -178,6 +180,7 @@ def _from_openapi_data(cls, id, type, created_at, query, detector_id, result_typ query (str): A question about the image. detector_id (str): Which detector was used on this image query? result_type (bool, date, datetime, dict, float, int, list, str, none_type): What type of result are we returning? + result (bool, date, datetime, dict, float, int, list, str, none_type): Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -210,7 +213,6 @@ def _from_openapi_data(cls, id, type, created_at, query, detector_id, result_typ Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - result (bool, date, datetime, dict, float, int, list, str, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) @@ -245,6 +247,7 @@ def _from_openapi_data(cls, id, type, created_at, query, detector_id, result_typ self.query = query self.detector_id = detector_id self.result_type = result_type + self.result = result for var_name, var_value in kwargs.items(): if ( var_name not in self.attribute_map @@ -303,7 +306,6 @@ def __init__(self, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - result (bool, date, datetime, dict, float, int, list, str, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) diff --git a/poetry.lock b/poetry.lock index 748907a5..6d2f7e5c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -16,7 +15,6 @@ files = [ name = "annotated-types" version = "0.5.0" description = "Reusable constraint types to use with typing.Annotated" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -31,7 +29,6 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} name = "argcomplete" version = "3.1.2" description = "Bash tab completion for argparse" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -49,7 +46,6 @@ test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] name = "astroid" version = "2.11.7" description = "An abstract syntax tree for Python with inference support." -category = "dev" optional = false python-versions = ">=3.6.2" files = [ @@ -68,7 +64,6 @@ wrapt = ">=1.11,<2" name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -90,7 +85,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "autodoc-pydantic" version = "2.0.1" description = "Seamlessly integrate pydantic models in your Sphinx documentation." -category = "dev" optional = false python-versions = ">=3.7.1,<4.0.0" files = [ @@ -99,6 +93,7 @@ files = [ ] [package.dependencies] +importlib-metadata = {version = ">1", markers = "python_version <= \"3.8\""} pydantic = ">=2.0,<3.0.0" pydantic-settings = ">=2.0,<3.0.0" Sphinx = ">=4.0" @@ -113,7 +108,6 @@ test = ["coverage (>=7,<8)", "pytest (>=7,<8)"] name = "babel" version = "2.13.0" description = "Internationalization utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -128,7 +122,6 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] name = "black" version = "23.3.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -179,7 +172,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -191,7 +183,6 @@ files = [ name = "cfgv" version = "3.3.1" description = "Validate configuration and produce human readable error messages." -category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -203,7 +194,6 @@ files = [ name = "chardet" version = "4.0.0" description = "Universal encoding detector for Python 2 and 3" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -215,7 +205,6 @@ files = [ name = "charset-normalizer" version = "3.3.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -315,7 +304,6 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -331,7 +319,6 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -343,7 +330,6 @@ files = [ name = "coverage" version = "7.2.7" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -419,7 +405,6 @@ toml = ["tomli"] name = "datamodel-code-generator" version = "0.22.1" description = "Datamodel Code Generator" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -452,7 +437,6 @@ http = ["httpx"] name = "dill" version = "0.3.7" description = "serialize all of Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -467,7 +451,6 @@ graph = ["objgraph (>=1.7.2)"] name = "distlib" version = "0.3.7" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" files = [ @@ -479,7 +462,6 @@ files = [ name = "dnspython" version = "2.3.0" description = "DNS toolkit" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -500,7 +482,6 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"] name = "dnspython" version = "2.4.2" description = "DNS toolkit" -category = "dev" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -520,7 +501,6 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"] name = "docutils" version = "0.18.1" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -532,7 +512,6 @@ files = [ name = "email-validator" version = "2.0.0.post2" description = "A robust email address syntax and deliverability validation library." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -548,7 +527,6 @@ idna = ">=2.0.0" name = "exceptiongroup" version = "1.1.3" description = "Backport of PEP 654 (exception groups)" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -563,7 +541,6 @@ test = ["pytest (>=6)"] name = "filelock" version = "3.12.2" description = "A platform independent file lock." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -579,7 +556,6 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "frozendict" version = "2.3.8" description = "A simple immutable dictionary" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -626,7 +602,6 @@ files = [ name = "genson" version = "1.2.2" description = "GenSON is a powerful, user-friendly JSON Schema generator." -category = "dev" optional = false python-versions = "*" files = [ @@ -637,7 +612,6 @@ files = [ name = "identify" version = "2.5.24" description = "File identification library for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -652,7 +626,6 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -664,7 +637,6 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -676,7 +648,6 @@ files = [ name = "importlib-metadata" version = "6.7.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -697,7 +668,6 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs name = "importlib-resources" version = "5.12.0" description = "Read resources from Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -716,7 +686,6 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec name = "inflect" version = "5.6.2" description = "Correctly generate plurals, singular nouns, ordinals, indefinite articles; convert numbers to words" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -732,7 +701,6 @@ testing = ["pygments", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdo name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -744,7 +712,6 @@ files = [ name = "isort" version = "5.11.5" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -762,7 +729,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -780,7 +746,6 @@ i18n = ["Babel (>=2.7)"] name = "jsonschema" version = "4.17.3" description = "An implementation of JSON Schema validation for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -804,7 +769,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-spec" version = "0.1.4" description = "JSONSchema Spec with object-oriented paths" -category = "dev" optional = false python-versions = ">=3.7.0,<4.0.0" files = [ @@ -822,7 +786,6 @@ typing-extensions = ">=4.3.0,<5.0.0" name = "lazy-object-proxy" version = "1.9.0" description = "A fast and thorough lazy object proxy." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -868,7 +831,6 @@ files = [ name = "markdown-it-py" version = "2.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -894,7 +856,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -918,16 +879,6 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -964,7 +915,6 @@ files = [ name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -976,7 +926,6 @@ files = [ name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -988,7 +937,6 @@ files = [ name = "mypy" version = "1.4.1" description = "Optional static typing for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1036,7 +984,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1048,7 +995,6 @@ files = [ name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -1059,49 +1005,10 @@ files = [ [package.dependencies] setuptools = "*" -[[package]] -name = "numpy" -version = "1.21.1" -description = "NumPy is the fundamental package for array computing with Python." -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "numpy-1.21.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:38e8648f9449a549a7dfe8d8755a5979b45b3538520d1e735637ef28e8c2dc50"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fd7d7409fa643a91d0a05c7554dd68aa9c9bb16e186f6ccfe40d6e003156e33a"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a75b4498b1e93d8b700282dc8e655b8bd559c0904b3910b144646dbbbc03e062"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1412aa0aec3e00bc23fbb8664d76552b4efde98fb71f60737c83efbac24112f1"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e46ceaff65609b5399163de5893d8f2a82d3c77d5e56d976c8b5fb01faa6b671"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c6a2324085dd52f96498419ba95b5777e40b6bcbc20088fddb9e8cbb58885e8e"}, - {file = "numpy-1.21.1-cp37-cp37m-win32.whl", hash = "sha256:73101b2a1fef16602696d133db402a7e7586654682244344b8329cdcbbb82172"}, - {file = "numpy-1.21.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7a708a79c9a9d26904d1cca8d383bf869edf6f8e7650d85dbc77b041e8c5a0f8"}, - {file = "numpy-1.21.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95b995d0c413f5d0428b3f880e8fe1660ff9396dcd1f9eedbc311f37b5652e16"}, - {file = "numpy-1.21.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:635e6bd31c9fb3d475c8f44a089569070d10a9ef18ed13738b03049280281267"}, - {file = "numpy-1.21.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a3d5fb89bfe21be2ef47c0614b9c9c707b7362386c9a3ff1feae63e0267ccb6"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a326af80e86d0e9ce92bcc1e65c8ff88297de4fa14ee936cb2293d414c9ec63"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:791492091744b0fe390a6ce85cc1bf5149968ac7d5f0477288f78c89b385d9af"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0318c465786c1f63ac05d7c4dbcecd4d2d7e13f0959b01b534ea1e92202235c5"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a513bd9c1551894ee3d31369f9b07460ef223694098cf27d399513415855b68"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91c6f5fc58df1e0a3cc0c3a717bb3308ff850abdaa6d2d802573ee2b11f674a8"}, - {file = "numpy-1.21.1-cp38-cp38-win32.whl", hash = "sha256:978010b68e17150db8765355d1ccdd450f9fc916824e8c4e35ee620590e234cd"}, - {file = "numpy-1.21.1-cp38-cp38-win_amd64.whl", hash = "sha256:9749a40a5b22333467f02fe11edc98f022133ee1bfa8ab99bda5e5437b831214"}, - {file = "numpy-1.21.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d7a4aeac3b94af92a9373d6e77b37691b86411f9745190d2c351f410ab3a791f"}, - {file = "numpy-1.21.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d9e7912a56108aba9b31df688a4c4f5cb0d9d3787386b87d504762b6754fbb1b"}, - {file = "numpy-1.21.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:25b40b98ebdd272bc3020935427a4530b7d60dfbe1ab9381a39147834e985eac"}, - {file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a92c5aea763d14ba9d6475803fc7904bda7decc2a0a68153f587ad82941fec1"}, - {file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05a0f648eb28bae4bcb204e6fd14603de2908de982e761a2fc78efe0f19e96e1"}, - {file = "numpy-1.21.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01f28075a92eede918b965e86e8f0ba7b7797a95aa8d35e1cc8821f5fc3ad6a"}, - {file = "numpy-1.21.1-cp39-cp39-win32.whl", hash = "sha256:88c0b89ad1cc24a5efbb99ff9ab5db0f9a86e9cc50240177a571fbe9c2860ac2"}, - {file = "numpy-1.21.1-cp39-cp39-win_amd64.whl", hash = "sha256:01721eefe70544d548425a07c80be8377096a54118070b8a62476866d5208e33"}, - {file = "numpy-1.21.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2d4d1de6e6fb3d28781c73fbde702ac97f03d79e4ffd6598b880b2d95d62ead4"}, - {file = "numpy-1.21.1.zip", hash = "sha256:dff4af63638afcc57a3dfb9e4b26d434a7a602d225b42d746ea7fe2edf1342fd"}, -] - [[package]] name = "openapi-schema-validator" version = "0.4.4" description = "OpenAPI schema validation for Python" -category = "dev" optional = false python-versions = ">=3.7.0,<4.0.0" files = [ @@ -1120,7 +1027,6 @@ docs = ["sphinx (>=5.3.0,<6.0.0)", "sphinx-immaterial (>=0.11.0,<0.12.0)"] name = "openapi-spec-validator" version = "0.5.7" description = "OpenAPI 2.0 (aka Swagger) and OpenAPI 3 spec validator" -category = "dev" optional = false python-versions = ">=3.7.0,<4.0.0" files = [ @@ -1140,7 +1046,6 @@ typing-extensions = {version = ">=4.5.0,<5.0.0", markers = "python_version < \"3 name = "packaging" version = "23.2" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1152,7 +1057,6 @@ files = [ name = "pathable" version = "0.4.3" description = "Object-oriented paths" -category = "dev" optional = false python-versions = ">=3.7.0,<4.0.0" files = [ @@ -1164,7 +1068,6 @@ files = [ name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1176,7 +1079,6 @@ files = [ name = "pillow" version = "9.5.0" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1256,7 +1158,6 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "pkgutil-resolve-name" version = "1.3.10" description = "Resolve a name to an object." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1268,7 +1169,6 @@ files = [ name = "platformdirs" version = "3.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1287,7 +1187,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1306,7 +1205,6 @@ testing = ["pytest", "pytest-benchmark"] name = "prance" version = "0.21.8.0" description = "Resolving Swagger/OpenAPI 2.0 and 3.0.0 Parser" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1333,7 +1231,6 @@ ssv = ["swagger-spec-validator (>=2.4,<3.0)"] name = "pre-commit" version = "2.21.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1353,7 +1250,6 @@ virtualenv = ">=20.10.0" name = "pydantic" version = "2.4.2" description = "Data validation using Python type hints" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1374,7 +1270,6 @@ email = ["email-validator (>=2.0.0)"] name = "pydantic-core" version = "2.10.1" description = "" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1493,7 +1388,6 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" name = "pydantic-settings" version = "2.0.3" description = "Settings management using Pydantic" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1509,7 +1403,6 @@ python-dotenv = ">=0.21.0" name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1524,7 +1417,6 @@ plugins = ["importlib-metadata"] name = "pylint" version = "2.13.9" description = "python code static checker" -category = "dev" optional = false python-versions = ">=3.6.2" files = [ @@ -1549,7 +1441,6 @@ testutil = ["gitpython (>3)"] name = "pyrsistent" version = "0.19.3" description = "Persistent/Functional/Immutable data structures" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1586,7 +1477,6 @@ files = [ name = "pysnooper" version = "1.2.0" description = "A poor man's debugger for Python." -category = "dev" optional = false python-versions = "*" files = [ @@ -1601,7 +1491,6 @@ tests = ["pytest"] name = "pytest" version = "7.4.2" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1625,7 +1514,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-cov" version = "3.0.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1644,7 +1532,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-markdown-docs" version = "0.4.3" description = "Run markdown code fences through pytest" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -1659,7 +1546,6 @@ markdown-it-py = ">=2.2.0,<2.3.0" name = "pytest-mock" version = "3.11.1" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1677,7 +1563,6 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -1690,14 +1575,13 @@ six = ">=1.5" [[package]] name = "python-dotenv" -version = "1.0.0" +version = "0.21.1" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "dev" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, - {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, + {file = "python-dotenv-0.21.1.tar.gz", hash = "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49"}, + {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"}, ] [package.extras] @@ -1707,7 +1591,6 @@ cli = ["click (>=5.0)"] name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1716,7 +1599,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1724,15 +1606,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -1749,7 +1624,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -1757,7 +1631,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -1767,7 +1640,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1789,7 +1661,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rfc3339-validator" version = "0.1.4" description = "A pure python RFC3339 validator" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1804,7 +1675,6 @@ six = "*" name = "ruamel-yaml" version = "0.17.35" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" -category = "dev" optional = false python-versions = ">=3" files = [ @@ -1823,42 +1693,35 @@ jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] name = "ruamel-yaml-clib" version = "0.2.8" description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" -category = "dev" optional = false python-versions = ">=3.6" files = [ {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:d92f81886165cb14d7b067ef37e142256f1c6a90a65cd156b063a43da1708cfd"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b5edda50e5e9e15e54a6a8a0070302b00c518a9d32accc2346ad6c984aacd279"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:7048c338b6c86627afb27faecf418768acb6331fc24cfa56c93e8c9780f815fa"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3fcc54cb0c8b811ff66082de1680b4b14cf8a81dce0d4fbf665c2265a81e07a1"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:665f58bfd29b167039f714c6998178d27ccd83984084c286110ef26b230f259f"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9eb5dee2772b0f704ca2e45b1713e4e5198c18f515b52743576d196348f374d3"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, @@ -1869,7 +1732,6 @@ files = [ name = "ruff" version = "0.0.261" description = "An extremely fast Python linter, written in Rust." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1896,7 +1758,6 @@ files = [ name = "semver" version = "2.13.0" description = "Python helper for Semantic Versioning (http://semver.org/)" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1908,7 +1769,6 @@ files = [ name = "setuptools" version = "68.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1925,7 +1785,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1937,7 +1796,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -1949,7 +1807,6 @@ files = [ name = "sphinx" version = "7.2.6" description = "Python documentation generator" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -1985,7 +1842,6 @@ test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools name = "sphinx-rtd-theme" version = "1.3.0" description = "Read the Docs theme for Sphinx" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -2005,7 +1861,6 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] name = "sphinxcontrib-applehelp" version = "1.0.7" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -2024,7 +1879,6 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "1.0.5" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -2043,7 +1897,6 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.0.4" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -2062,7 +1915,6 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jquery" version = "4.1" description = "Extension to include jQuery on newer Sphinx releases" -category = "dev" optional = false python-versions = ">=2.7" files = [ @@ -2077,7 +1929,6 @@ Sphinx = ">=1.8" name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2092,7 +1943,6 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-qthelp" version = "1.0.6" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -2111,7 +1961,6 @@ test = ["pytest"] name = "sphinxcontrib-serializinghtml" version = "1.1.9" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -2130,7 +1979,6 @@ test = ["pytest"] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2142,7 +1990,6 @@ files = [ name = "toml-sort" version = "0.23.1" description = "Toml sorting library" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -2157,7 +2004,6 @@ tomlkit = ">=0.11.2" name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2169,7 +2015,6 @@ files = [ name = "tomlkit" version = "0.12.1" description = "Style preserving TOML library" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2181,7 +2026,6 @@ files = [ name = "typed-ast" version = "1.5.5" description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2232,7 +2076,6 @@ files = [ name = "typer" version = "0.9.0" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2254,7 +2097,6 @@ test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6. name = "types-requests" version = "2.31.0.6" description = "Typing stubs for requests" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2269,7 +2111,6 @@ types-urllib3 = "*" name = "types-urllib3" version = "1.26.25.14" description = "Typing stubs for urllib3" -category = "dev" optional = false python-versions = "*" files = [ @@ -2281,7 +2122,6 @@ files = [ name = "typing-extensions" version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2293,7 +2133,6 @@ files = [ name = "urllib3" version = "1.26.17" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -2310,7 +2149,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "virtualenv" version = "20.24.5" description = "Virtual Python Environment builder" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2332,7 +2170,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -2417,7 +2254,6 @@ files = [ name = "zipp" version = "3.15.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2432,4 +2268,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = ">=3.7.0,<4.0" -content-hash = "e8c0b961966be8c217e0d48b71ce4bfd0753bf062eef1dacf1f6508aae8d4d85" +content-hash = "efa0586964555cb06603385a123ade083f101af28d45999f1015d0b8a324ffe0" diff --git a/pyproject.toml b/pyproject.toml index d3464015..b8828095 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,6 @@ Sphinx = {version = "7.2.6", python = ">=3.9.0,<4.0"} sphinx-rtd-theme = {version = "1.3.0", python = ">=3.9.0,<4.0"} autodoc-pydantic = {version = "2.0.1", python = ">=3.9.0,<4.0"} toml = "0.10.2" -pillow = "^9.0.0" [tool.poetry.scripts] groundlight = "groundlight.cli:groundlight" diff --git a/spec/public-api.yaml b/spec/public-api.yaml index 8dd436ea..871f1d65 100644 --- a/spec/public-api.yaml +++ b/spec/public-api.yaml @@ -12,105 +12,105 @@ paths: operationId: List detectors description: Retrieve a list of detectors. parameters: - - name: page - required: false - in: query - description: A page number within the paginated result set. - schema: - type: integer - - name: page_size - required: false - in: query - description: Number of results to return per page. - schema: - type: integer + - name: page + required: false + in: query + description: A page number within the paginated result set. + schema: + type: integer + - name: page_size + required: false + in: query + description: Number of results to return per page. + schema: + type: integer tags: - - detectors + - detectors security: - - ApiToken: [] + - ApiToken: [] responses: - "200": + '200': content: application/json: schema: - $ref: "#/components/schemas/PaginatedDetectorList" - description: "" + $ref: '#/components/schemas/PaginatedDetectorList' + description: '' post: operationId: Create detector description: Create a new detector. tags: - - detectors + - detectors requestBody: content: application/json: schema: - $ref: "#/components/schemas/DetectorCreationInput" + $ref: '#/components/schemas/DetectorCreationInput' application/x-www-form-urlencoded: schema: - $ref: "#/components/schemas/DetectorCreationInput" + $ref: '#/components/schemas/DetectorCreationInput' multipart/form-data: schema: - $ref: "#/components/schemas/DetectorCreationInput" + $ref: '#/components/schemas/DetectorCreationInput' required: true security: - - ApiToken: [] + - ApiToken: [] responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/Detector" - description: "" + $ref: '#/components/schemas/Detector' + description: '' /v1/detectors/{id}: get: operationId: Get detector description: Retrieve a detector by its ID. parameters: - - in: path - name: id - schema: - type: string - description: Choose a detector by its ID. - required: true + - in: path + name: id + schema: + type: string + description: Choose a detector by its ID. + required: true tags: - - detectors + - detectors security: - - ApiToken: [] + - ApiToken: [] responses: - "200": + '200': content: application/json: schema: - $ref: "#/components/schemas/Detector" - description: "" + $ref: '#/components/schemas/Detector' + description: '' /v1/image-queries: get: operationId: List image queries description: Retrieve a list of image-queries. parameters: - - name: page - required: false - in: query - description: A page number within the paginated result set. - schema: - type: integer - - name: page_size - required: false - in: query - description: Number of results to return per page. - schema: - type: integer + - name: page + required: false + in: query + description: A page number within the paginated result set. + schema: + type: integer + - name: page_size + required: false + in: query + description: Number of results to return per page. + schema: + type: integer tags: - - image-queries + - image-queries security: - - ApiToken: [] + - ApiToken: [] responses: - "200": + '200': content: application/json: schema: - $ref: "#/components/schemas/PaginatedImageQueryList" - description: "" + $ref: '#/components/schemas/PaginatedImageQueryList' + description: '' post: operationId: Submit image query description: |2+ @@ -126,35 +126,30 @@ paths: ``` parameters: - - in: query - name: detector_id - schema: - type: string - description: Choose a detector by its ID. - required: true - - in: query - name: human_review - schema: - type: string - description: > - 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. - required: false - - in: query - name: patience_time - schema: - type: number - format: float - description: How long to wait for a confident response. - required: false - - in: query - name: want_async - schema: - type: string - description: If "true" then submitting an image query returns immediately without a result. The result will be computed asynchronously and can be retrieved later. + - in: query + name: detector_id + schema: + type: string + description: Choose a detector by its ID. + required: true + - in: query + name: human_review + schema: + type: string + description: > + 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. + required: false + - in: query + name: patience_time + schema: + type: number + format: float + description: How long to wait for a confident response. + required: false tags: - - image-queries + - image-queries requestBody: content: image/jpeg: @@ -163,45 +158,44 @@ paths: format: binary examples: JPEGBinaryImageData: - value: "@path/to/image.jpeg" + value: '@path/to/image.jpeg' summary: JPEG binary image data security: - - ApiToken: [] + - ApiToken: [] responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/ImageQuery" - description: "" + $ref: '#/components/schemas/ImageQuery' + description: '' /v1/image-queries/{id}: get: operationId: Get image query description: Retrieve an image-query by its ID. parameters: - - in: path - name: id - schema: - type: string - description: Choose an image query by its ID. - required: true + - in: path + name: id + schema: + type: string + description: Choose an image query by its ID. + required: true tags: - - image-queries + - image-queries security: - - ApiToken: [] + - ApiToken: [] responses: - "200": + '200': content: application/json: schema: - $ref: "#/components/schemas/ImageQuery" - description: "" + $ref: '#/components/schemas/ImageQuery' + description: '' components: schemas: ClassificationResult: type: object - description: - Our classification result. This result can come from the detector, + description: Our classification result. This result can come from the detector, or a human reviewer. properties: confidence: @@ -209,14 +203,13 @@ components: maximum: 1 minimum: 0 nullable: true - description: - On a scale of 0 to 1, how confident are we in the predicted + description: On a scale of 0 to 1, how confident are we in the predicted label? label: type: string description: What is the predicted label? required: - - label + - label x-internal: true Detector: type: object @@ -228,7 +221,7 @@ components: description: A unique ID for this object. type: allOf: - - $ref: "#/components/schemas/DetectorTypeEnum" + - $ref: '#/components/schemas/DetectorTypeEnum' readOnly: true description: The type of this object. created_at: @@ -254,16 +247,15 @@ components: maximum: 1.0 minimum: 0.0 default: 0.9 - description: - If the detector's prediction is below this confidence threshold, + description: If the detector's prediction is below this confidence threshold, send the image query for human review. required: - - created_at - - group_name - - id - - name - - query - - type + - created_at + - group_name + - id + - name + - query + - type x-internal: true DetectorCreationInput: type: object @@ -287,8 +279,7 @@ components: maximum: 1.0 minimum: 0.0 default: 0.9 - description: - If the detector's prediction is below this confidence threshold, + description: If the detector's prediction is below this confidence threshold, send the image query for human review. pipeline_config: type: string @@ -296,13 +287,13 @@ components: description: (Advanced usage) Configuration to instantiate a specific prediction pipeline. maxLength: 8192 required: - # TODO: make name optional - that's how the web version is going. - - name - - query + # TODO: make name optional - that's how the web version is going. + - name + - query x-internal: true DetectorTypeEnum: enum: - - detector + - detector type: string ImageQuery: type: object @@ -314,7 +305,7 @@ components: description: A unique ID for this object. type: allOf: - - $ref: "#/components/schemas/ImageQueryTypeEnum" + - $ref: '#/components/schemas/ImageQueryTypeEnum' readOnly: true description: The type of this object. created_at: @@ -332,24 +323,25 @@ components: description: Which detector was used on this image query? result_type: allOf: - - $ref: "#/components/schemas/ResultTypeEnum" + - $ref: '#/components/schemas/ResultTypeEnum' readOnly: true description: What type of result are we returning? result: allOf: - - $ref: "#/components/schemas/ClassificationResult" + - $ref: '#/components/schemas/ClassificationResult' readOnly: true required: - - created_at - - detector_id - - id - - query - - result_type - - type + - created_at + - detector_id + - id + - query + - result + - result_type + - type x-internal: true ImageQueryTypeEnum: enum: - - image_query + - image_query type: string PaginatedDetectorList: type: object @@ -370,7 +362,7 @@ components: results: type: array items: - $ref: "#/components/schemas/Detector" + $ref: '#/components/schemas/Detector' PaginatedImageQueryList: type: object properties: @@ -390,10 +382,10 @@ components: results: type: array items: - $ref: "#/components/schemas/ImageQuery" + $ref: '#/components/schemas/ImageQuery' ResultTypeEnum: enum: - - binary_classification + - binary_classification type: string securitySchemes: ApiToken: @@ -401,11 +393,11 @@ components: type: apiKey in: header servers: - - url: https://api.groundlight.ai/device-api - description: Prod - - url: https://api.integ.groundlight.ai/device-api - description: Integ - - url: https://device.positronix.ai/device-api - description: Device Prod - - url: https://device.integ.positronix.ai/device-api - description: Device Integ +- url: https://api.groundlight.ai/device-api + description: Prod +- url: https://api.integ.groundlight.ai/device-api + description: Integ +- url: https://device.positronix.ai/device-api + description: Device Prod +- url: https://device.integ.positronix.ai/device-api + description: Device Integ diff --git a/sphinx_docs/conf.py b/sphinx_docs/conf.py index d7aa69ee..e05c8d8b 100644 --- a/sphinx_docs/conf.py +++ b/sphinx_docs/conf.py @@ -45,4 +45,4 @@ def get_version_name() -> str: # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output html_theme = "sphinx_rtd_theme" -html_static_path = ["_static"] +html_static_path = ["_static"] \ No newline at end of file diff --git a/src/groundlight/binary_labels.py b/src/groundlight/binary_labels.py index de3216a1..a0f615b4 100644 --- a/src/groundlight/binary_labels.py +++ b/src/groundlight/binary_labels.py @@ -15,25 +15,19 @@ class Label(str, Enum): YES = "YES" NO = "NO" - UNCLEAR = "UNCLEAR" + UNSURE = "UNSURE" -VALID_DISPLAY_LABELS = {Label.YES, Label.NO, Label.UNCLEAR} +VALID_DISPLAY_LABELS = {Label.YES, Label.NO, Label.UNSURE} class DeprecatedLabel(str, Enum): PASS = "PASS" FAIL = "FAIL" NEEDS_REVIEW = "NEEDS_REVIEW" - UNSURE = "__UNSURE" -DEPRECATED_LABEL_NAMES = { - DeprecatedLabel.PASS, - DeprecatedLabel.FAIL, - DeprecatedLabel.NEEDS_REVIEW, - DeprecatedLabel.UNSURE, -} +DEPRECATED_LABEL_NAMES = {DeprecatedLabel.PASS, DeprecatedLabel.FAIL, DeprecatedLabel.NEEDS_REVIEW} def convert_internal_label_to_display( @@ -53,8 +47,8 @@ def convert_internal_label_to_display( return Label.YES if upper in {Label.NO, DeprecatedLabel.FAIL}: return Label.NO - if upper in {Label.UNCLEAR, DeprecatedLabel.NEEDS_REVIEW, DeprecatedLabel.UNSURE}: - return Label.UNCLEAR + if upper in {Label.UNSURE, DeprecatedLabel.NEEDS_REVIEW}: + return Label.UNSURE logger.warning(f"Unrecognized internal label {label} - leaving it alone as a string.") return label diff --git a/src/groundlight/cli.py b/src/groundlight/cli.py index 7ea962d5..9c967fae 100644 --- a/src/groundlight/cli.py +++ b/src/groundlight/cli.py @@ -5,36 +5,18 @@ from typing_extensions import get_origin from groundlight import Groundlight -from groundlight.client import ApiTokenError -from groundlight.config import API_TOKEN_HELP_MESSAGE -cli_app = typer.Typer( - no_args_is_help=True, - context_settings={"help_option_names": ["-h", "--help"], "max_content_width": 800}, -) +cli_app = typer.Typer(no_args_is_help=True, context_settings={"help_option_names": ["-h", "--help"]}) def class_func_to_cli(method): """ - Given the class method, create a method with the identical signature to provide the help documentation and - but only instantiates the class when the method is actually called. + Given the class method, simplify the typing on the inputs so that Typer can accept the method """ - # We create a fake class and fake method so we have the correct annotations for typer to use - # When we wrap the fake method, we only use the fake method's name to access the real method - # and attach it to a Groundlight instance that we create at function call time - class FakeClass: - pass - - fake_instance = FakeClass() - fake_method = method.__get__(fake_instance, FakeClass) - - @wraps(fake_method) + @wraps(method) def wrapper(*args, **kwargs): - gl = Groundlight() - gl_method = vars(Groundlight)[fake_method.__name__] - gl_bound_method = gl_method.__get__(gl, Groundlight) - print(gl_bound_method(*args, **kwargs)) # this is where we output to the console + print(method(*args, **kwargs)) # this is where we output to the console # not recommended practice to directly change annotations, but gets around Typer not supporting Union types for name, annotation in method.__annotations__.items(): @@ -48,15 +30,15 @@ def wrapper(*args, **kwargs): def groundlight(): - try: - # For each method in the Groundlight class, create a function that can be called from the command line - for name, method in vars(Groundlight).items(): - if callable(method) and not name.startswith("_"): - cli_func = class_func_to_cli(method) - cli_app.command()(cli_func) - cli_app() - except ApiTokenError: - print(API_TOKEN_HELP_MESSAGE) + gl = Groundlight() + + # For each method in the Groundlight class, create a function that can be called from the command line + for name, method in vars(Groundlight).items(): + if callable(method) and not name.startswith("_"): + attached_method = method.__get__(gl) + cli_func = class_func_to_cli(attached_method) + cli_app.command()(cli_func) + cli_app() if __name__ == "__main__": diff --git a/src/groundlight/client.py b/src/groundlight/client.py index 74c00980..fe892e39 100644 --- a/src/groundlight/client.py +++ b/src/groundlight/client.py @@ -11,7 +11,7 @@ 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.config import API_TOKEN_HELP_MESSAGE, API_TOKEN_VARIABLE_NAME +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, @@ -88,7 +88,13 @@ def __init__(self, endpoint: Optional[str] = None, api_token: Optional[str] = No # Retrieve the API token from environment variable api_token = os.environ[API_TOKEN_VARIABLE_NAME] except KeyError as e: - raise ApiTokenError(API_TOKEN_HELP_MESSAGE) from e + raise ApiTokenError( + ( + "No API token found. Please put your token in an environment variable " + f'named "{API_TOKEN_VARIABLE_NAME}". If you don\'t have a token, you can ' + f"create one at {API_TOKEN_WEB_URL}" + ), + ) from e configuration.api_key["ApiToken"] = api_token @@ -102,10 +108,7 @@ def _fixup_image_query(iq: ImageQuery) -> ImageQuery: Process the wire-format image query to make it more usable. """ # Note: This might go away once we clean up the mapping logic server-side. - - # we have to check that result is not None because the server will return a result of None if want_async=True - if iq.result is not None: - iq.result.label = convert_internal_label_to_display(iq, iq.result.label) + iq.result.label = convert_internal_label_to_display(iq, iq.result.label) return iq def get_detector(self, id: Union[str, Detector]) -> Detector: # pylint: disable=redefined-builtin @@ -360,7 +363,6 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments patience_time: Optional[float] = None, confidence_threshold: Optional[float] = None, human_review: Optional[str] = None, - want_async: bool = False, inspection_id: Optional[str] = None, ) -> ImageQuery: """ @@ -387,11 +389,6 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments If set to `NEVER`, never send the image query for human review. :type human_review: str - :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. Must set `wait` to 0 to use - want_async. - :type want_async: bool - :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. :type inspection_id: str @@ -413,15 +410,6 @@ 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 wait must be set to 0 to use - # want_async. - if wait != 0: - raise ValueError( - "wait must be set to 0 to use want_async. Using wait and want_async at the same time is incompatible." # noqa: E501 - ) - params["want_async"] = str(bool(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 # provided, we use the private API client instead. @@ -434,55 +422,13 @@ def submit_image_query( # noqa: PLR0913 # pylint: disable=too-many-arguments image_query = self.get_image_query(iq_id) if wait: - threshold = self.get_detector(detector).confidence_threshold + if confidence_threshold is None: + threshold = self.get_detector(detector).confidence_threshold + else: + threshold = confidence_threshold image_query = self.wait_for_confident_result(image_query, confidence_threshold=threshold, timeout_sec=wait) - return self._fixup_image_query(image_query) - def ask_async( - self, - detector: Union[Detector, str], - image: Union[str, bytes, Image.Image, BytesIO, BufferedReader, np.ndarray], - human_review: Optional[str] = None, - inspection_id: Optional[str] = None, - ) -> ImageQuery: - """ - Convenience method for submitting an `ImageQuery` asynchronously. This is equivalent to calling - `submit_image_query` with `want_async=True` and `wait=0`. Use `get_image_query` to retrieve the `result` of the - ImageQuery. - - :param detector: the Detector object, or string id of a detector like `det_12345` - :type detector: Detector or str - - :param image: The image, in several possible formats: - - - filename (string) of a jpeg file - - byte array or BytesIO or BufferedReader with jpeg bytes - - numpy array with values 0-255 and dimensions (H,W,3) in BGR order - (Note OpenCV uses BGR not RGB. `img[:, :, ::-1]` will reverse the channels) - - PIL Image: Any binary format must be JPEG-encoded already. - Any pixel format will get converted to JPEG at high quality before sending to service. - - :type image: str or bytes or Image.Image or BytesIO or BufferedReader or np.ndarray - - :param human_review: If `None` or `DEFAULT`, send the image query for human review - 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. - :type human_review: str - - :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. - :type inspection_id: str - - :return ImageQuery - :rtype ImageQuery - - """ - return self.submit_image_query( - detector, image, wait=0, human_review=human_review, want_async=True, inspection_id=inspection_id - ) - def wait_for_confident_result( self, image_query: Union[ImageQuery, str], diff --git a/src/groundlight/config.py b/src/groundlight/config.py index c92acb32..2eb592ff 100644 --- a/src/groundlight/config.py +++ b/src/groundlight/config.py @@ -8,9 +8,3 @@ "API_TOKEN_VARIABLE_NAME", "DEFAULT_ENDPOINT", ] - -API_TOKEN_HELP_MESSAGE = ( - "No API token found. Please put your token in an environment variable " - f'named "{API_TOKEN_VARIABLE_NAME}". If you don\'t have a token, you can ' - f"create one at {API_TOKEN_WEB_URL}" -) diff --git a/test/integration/test_groundlight.py b/test/integration/test_groundlight.py index 71e9da1e..f8f8246d 100644 --- a/test/integration/test_groundlight.py +++ b/test/integration/test_groundlight.py @@ -1,7 +1,6 @@ # Optional star-imports are weird and not usually recommended ... # ruff: noqa: F403,F405 # pylint: disable=wildcard-import,unused-wildcard-import,redefined-outer-name,import-outside-toplevel -import time from datetime import datetime from typing import Any @@ -280,62 +279,6 @@ def test_submit_image_query_pil(gl: Groundlight, detector: Detector): _image_query = gl.submit_image_query(detector=detector.id, image=black) -def test_submit_image_query_wait_and_want_async_causes_exception(gl: Groundlight, detector: Detector): - """ - Tests that attempting to use the wait and want_async parameters together causes an exception. - """ - - with pytest.raises(ValueError): - _image_query = gl.submit_image_query( - detector=detector.id, image="test/assets/dog.jpeg", wait=10, want_async=True - ) - - -def test_submit_image_query_with_want_async_workflow(gl: Groundlight, detector: Detector): - """ - Tests the workflow for submitting an image query with the want_async parameter set to True. - """ - - _image_query = gl.submit_image_query(detector=detector.id, image="test/assets/dog.jpeg", wait=0, want_async=True) - - # the result should be None - assert _image_query.result is None - - # attempting to access fields within the result should raise an exception - with pytest.raises(AttributeError): - _ = _image_query.result.label # type: ignore - with pytest.raises(AttributeError): - _ = _image_query.result.confidence # type: ignore - time.sleep(5) - # you should be able to get a "real" result by retrieving an updated image query object from the server - _image_query = gl.get_image_query(id=_image_query.id) - assert _image_query.result is not None - assert _image_query.result.label in VALID_DISPLAY_LABELS - - -def test_ask_async_workflow(gl: Groundlight, detector: Detector): - """ - Tests the workflow for submitting an image query with ask_async. - """ - _image_query = gl.ask_async(detector=detector.id, image="test/assets/dog.jpeg") - - # the result should be None - assert _image_query.result is None - - # attempting to access fields within the result should raise an exception - with pytest.raises(AttributeError): - _ = _image_query.result.label # type: ignore - with pytest.raises(AttributeError): - _ = _image_query.result.confidence # type: ignore - - time.sleep(5) - - # you should be able to get a "real" result by retrieving an updated image query object from the server - _image_query = gl.get_image_query(id=_image_query.id) - assert _image_query.result is not None - assert _image_query.result.label in VALID_DISPLAY_LABELS - - def test_list_image_queries(gl: Groundlight): image_queries = gl.list_image_queries() assert str(image_queries) @@ -430,7 +373,7 @@ def test_add_label_names(gl: Groundlight, image_query_yes: ImageQuery, image_que # We may want to support something like this in the future, but not yet with pytest.raises(ValueError): - gl.add_label(iqid_yes, Label.UNCLEAR) + gl.add_label(iqid_yes, Label.UNSURE) def test_label_conversion_produces_strings(): diff --git a/test/unit/test_cli.py b/test/unit/test_cli.py index 9e8b99fe..1558245f 100644 --- a/test/unit/test_cli.py +++ b/test/unit/test_cli.py @@ -1,8 +1,6 @@ -import os import re import subprocess from datetime import datetime -from unittest.mock import patch def test_list_detector(): @@ -74,19 +72,12 @@ def test_detector_and_image_queries(): assert completed_process.returncode == 0 -@patch.dict(os.environ, {}) def test_help(): completed_process = subprocess.run(["groundlight"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) assert completed_process.returncode == 0 - completed_process = subprocess.run(["groundlight", "-h"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - assert completed_process.returncode == 0 - completed_process = subprocess.run( - ["groundlight", "--help"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True - ) + completed_process = subprocess.run(["groundlight"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) assert completed_process.returncode == 0 - completed_process = subprocess.run( - ["groundlight", "get-detector", "-h"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True - ) + completed_process = subprocess.run(["groundlight"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) assert completed_process.returncode == 0