From 6e55eda62700a5f326e075d7670f35b4123b27d7 Mon Sep 17 00:00:00 2001 From: Leo Dirac Date: Fri, 31 Mar 2023 03:04:58 +0000 Subject: [PATCH 1/5] Fixing bad breaking bug in url-sanitization. --- src/groundlight/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/groundlight/client.py b/src/groundlight/client.py index b83989a8..7a297d62 100644 --- a/src/groundlight/client.py +++ b/src/groundlight/client.py @@ -51,7 +51,7 @@ def __init__(self, endpoint: str = DEFAULT_ENDPOINT, api_token: str = None): """ # Specify the endpoint self.endpoint = sanitize_endpoint_url(endpoint) - configuration = Configuration(host=endpoint) + configuration = Configuration(host=self.endpoint) if api_token is None: try: From ec6468d2061aa112296c530dc07567e8fdab43a3 Mon Sep 17 00:00:00 2001 From: Leo Dirac Date: Fri, 31 Mar 2023 03:16:15 +0000 Subject: [PATCH 2/5] If you accidentally set the endpoint to a blank string, it works. --- src/groundlight/config.py | 4 +--- src/groundlight/internalapi.py | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/groundlight/config.py b/src/groundlight/config.py index 039fc52c..2eb592ff 100644 --- a/src/groundlight/config.py +++ b/src/groundlight/config.py @@ -1,9 +1,7 @@ -import os - API_TOKEN_WEB_URL = "https://app.groundlight.ai/reef/my-account/api-tokens" API_TOKEN_VARIABLE_NAME = "GROUNDLIGHT_API_TOKEN" -DEFAULT_ENDPOINT = os.environ.get("GROUNDLIGHT_ENDPOINT", "https://api.groundlight.ai/") +DEFAULT_ENDPOINT = "https://api.groundlight.ai/" __all__ = [ "API_TOKEN_WEB_URL", diff --git a/src/groundlight/internalapi.py b/src/groundlight/internalapi.py index a1a84fed..80a4c946 100644 --- a/src/groundlight/internalapi.py +++ b/src/groundlight/internalapi.py @@ -3,6 +3,7 @@ import uuid from typing import Dict from urllib.parse import urlsplit, urlunsplit +from groundlight.config import DEFAULT_ENDPOINT import model import requests @@ -17,6 +18,8 @@ def sanitize_endpoint_url(endpoint: str) -> str: This allows people to leave that off entirely, or add a trailing slash. Also some future-proofing by allowing "v1" or "v2" or "v3" paths. """ + if not endpoint: + endpoint = os.environ.get("GROUNDLIGHT_ENDPOINT", "https://api.groundlight.ai/") parts = urlsplit(endpoint) if (parts.scheme not in ("http", "https")) or (not parts.netloc): raise ValueError( From b2d528b8dffa7f1d62f5e288e33927e6180e8e65 Mon Sep 17 00:00:00 2001 From: Leo Dirac Date: Fri, 31 Mar 2023 03:18:23 +0000 Subject: [PATCH 3/5] Fixing imagequery prefix. Changing default test env to prod. --- Makefile | 4 ++-- pyproject.toml | 2 +- src/groundlight/client.py | 1 + test/integration/test_groundlight.py | 5 ++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 90a0146f..8a8932ee 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,8 @@ generate: install ## Generate the SDK from our public openapi spec test-local: install ## Run integration tests against an API server running at http://localhost:8000/device-api (needs GROUNDLIGHT_API_TOKEN) - GROUNDLIGHT_TEST_API_ENDPOINT="http://localhost:8000/device-api" poetry run pytest --cov=src test --log-cli-level INFO + GROUNDLIGHT_API_ENDPOINT="http://localhost:8000/" poetry run pytest --cov=src test --log-cli-level INFO test-integ: install ## Run integration tests against the integ API server (needs GROUNDLIGHT_API_TOKEN) - GROUNDLIGHT_TEST_API_ENDPOINT="https://api.integ.groundlight.ai/device-api" poetry run pytest --cov=src test --log-cli-level INFO + GROUNDLIGHT_API_ENDPOINT="https://api.integ.groundlight.ai/" poetry run pytest --cov=src test --log-cli-level INFO diff --git a/pyproject.toml b/pyproject.toml index 2b74e929..942e0805 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "groundlight" -version = "0.7.0" +version = "0.7.1" license = "MIT" readme = "README.md" homepage = "https://www.groundlight.ai" diff --git a/src/groundlight/client.py b/src/groundlight/client.py index 7a297d62..6c1364d7 100644 --- a/src/groundlight/client.py +++ b/src/groundlight/client.py @@ -201,6 +201,7 @@ def add_label(self, image_query: Union[ImageQuery, str], label: str): image_query_id = image_query.id else: image_query_id = str(image_query) + # Some old imagequery id's started with "chk_" if not (image_query_id.startswith("chk_") or image_query_id.startswith("iq_")): raise ValueError(f"Invalid image query id {image_query_id}") api_label = convert_display_label_to_internal(image_query_id, label) diff --git a/test/integration/test_groundlight.py b/test/integration/test_groundlight.py index cb796ca0..5bf840ba 100644 --- a/test/integration/test_groundlight.py +++ b/test/integration/test_groundlight.py @@ -12,8 +12,7 @@ @pytest.fixture def gl() -> Groundlight: """Creates a Groundlight client object for testing.""" - endpoint = os.environ.get("GROUNDLIGHT_TEST_API_ENDPOINT", "http://localhost:8000/device-api") - return Groundlight(endpoint=endpoint) + return Groundlight() @pytest.fixture @@ -121,7 +120,7 @@ def test_add_label_to_object(gl: Groundlight, image_query: ImageQuery): def test_add_label_by_id(gl: Groundlight, image_query: ImageQuery): iqid = image_query.id - assert iqid.startswith("chk_") # someday we'll probably change this to iq_ + assert iqid.startswith("iq_") gl.add_label(iqid, "No") From def1930aceee10d793b41b7001e2b8a649c0d9e1 Mon Sep 17 00:00:00 2001 From: Leo Dirac Date: Fri, 31 Mar 2023 03:31:58 +0000 Subject: [PATCH 4/5] Fixing integ tests to point at integ. --- Makefile | 4 ++-- src/groundlight/client.py | 2 +- src/groundlight/internalapi.py | 4 +++- test/integration/test_groundlight.py | 6 ++++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 8a8932ee..35619819 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,8 @@ generate: install ## Generate the SDK from our public openapi spec test-local: install ## Run integration tests against an API server running at http://localhost:8000/device-api (needs GROUNDLIGHT_API_TOKEN) - GROUNDLIGHT_API_ENDPOINT="http://localhost:8000/" poetry run pytest --cov=src test --log-cli-level INFO + GROUNDLIGHT_ENDPOINT="http://localhost:8000/" poetry run pytest --cov=src test --log-cli-level INFO test-integ: install ## Run integration tests against the integ API server (needs GROUNDLIGHT_API_TOKEN) - GROUNDLIGHT_API_ENDPOINT="https://api.integ.groundlight.ai/" poetry run pytest --cov=src test --log-cli-level INFO + GROUNDLIGHT_ENDPOINT="https://api.integ.groundlight.ai/" poetry run pytest --cov=src test --log-cli-level INFO diff --git a/src/groundlight/client.py b/src/groundlight/client.py index 6c1364d7..7310a1a9 100644 --- a/src/groundlight/client.py +++ b/src/groundlight/client.py @@ -43,7 +43,7 @@ class Groundlight: POLLING_EXPONENTIAL_BACKOFF = 1.3 # This still has the nice backoff property that the max number of requests # is O(log(time)), but with 1.3 the guarantee is that the call will return no more than 30% late - def __init__(self, endpoint: str = DEFAULT_ENDPOINT, api_token: str = None): + def __init__(self, endpoint: Optional[str] = None, api_token: str = None): """ :param endpoint: optionally specify a different endpoint :param api_token: use this API token for your API calls. If unset, fallback to the diff --git a/src/groundlight/internalapi.py b/src/groundlight/internalapi.py index 80a4c946..a6438cc1 100644 --- a/src/groundlight/internalapi.py +++ b/src/groundlight/internalapi.py @@ -1,8 +1,10 @@ import logging +import os import time -import uuid from typing import Dict from urllib.parse import urlsplit, urlunsplit +import uuid + from groundlight.config import DEFAULT_ENDPOINT import model diff --git a/test/integration/test_groundlight.py b/test/integration/test_groundlight.py index 5bf840ba..7fee6f6a 100644 --- a/test/integration/test_groundlight.py +++ b/test/integration/test_groundlight.py @@ -25,7 +25,8 @@ def detector(gl: Groundlight) -> Detector: @pytest.fixture def image_query(gl: Groundlight, detector: Detector) -> ImageQuery: - return gl.submit_image_query(detector=detector.id, image="test/assets/dog.jpeg") + iq = gl.submit_image_query(detector=detector.id, image="test/assets/dog.jpeg") + return iq def test_create_detector(gl: Groundlight): @@ -120,7 +121,8 @@ def test_add_label_to_object(gl: Groundlight, image_query: ImageQuery): def test_add_label_by_id(gl: Groundlight, image_query: ImageQuery): iqid = image_query.id - assert iqid.startswith("iq_") + # TODO: Fully deprecate chk_ prefix + assert iqid.startswith("chk_") or iqid.startswith("iq_") gl.add_label(iqid, "No") From d1bc2f8ab9bb18c782fe04d6e6eada0423617d32 Mon Sep 17 00:00:00 2001 From: Leo Dirac Date: Fri, 31 Mar 2023 03:39:12 +0000 Subject: [PATCH 5/5] Explicitly dealing with blank environment variable. --- src/groundlight/internalapi.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/groundlight/internalapi.py b/src/groundlight/internalapi.py index a6438cc1..3f95d46f 100644 --- a/src/groundlight/internalapi.py +++ b/src/groundlight/internalapi.py @@ -21,7 +21,10 @@ def sanitize_endpoint_url(endpoint: str) -> str: Also some future-proofing by allowing "v1" or "v2" or "v3" paths. """ if not endpoint: - endpoint = os.environ.get("GROUNDLIGHT_ENDPOINT", "https://api.groundlight.ai/") + endpoint = os.environ.get("GROUNDLIGHT_ENDPOINT", "") + if not endpoint: + # Because sometimes people set an environment variable to a blank string by mistake + endpoint = "https://api.groundlight.ai/" parts = urlsplit(endpoint) if (parts.scheme not in ("http", "https")) or (not parts.netloc): raise ValueError(