Skip to content

Commit 82e03c0

Browse files
author
Val Brodsky
committed
Refactor IntegrationClient into a separate file
Add AdminClient Add Ephemeral client. Test for ephemeral client
1 parent 30b78d0 commit 82e03c0

File tree

5 files changed

+263
-194
lines changed

5 files changed

+263
-194
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ test-ephemeral: build-image
6464
docker run -it --rm -v ${PWD}:/usr/src -w /usr/src \
6565
-e LABELBOX_TEST_ENVIRON="ephemeral" \
6666
-e DA_GCP_LABELBOX_API_KEY=${DA_GCP_LABELBOX_API_KEY} \
67-
-e LABELBOX_TEST_API_KEY_EPHEMERAL=${LABELBOX_TEST_API_KEY_LOCAL} \
68-
-e FIXTURE_PROFILE=true \
67+
-e SERVICE_API_KEY=${SERVICE_API_KEY} \
68+
-e LABELBOX_TEST_BASE_URL="http://host.docker.internal:8080" \
6969
local/labelbox-python:test pytest $(PATH_TO_TEST)

tests/integration/conftest.py

Lines changed: 8 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,34 @@
22
from itertools import islice
33
import json
44
import os
5-
import re
65
import sys
76
import time
87
import uuid
9-
from enum import Enum
108
from types import SimpleNamespace
11-
from typing import Type, List, Union
9+
from typing import Type, List
1210

1311
import pytest
1412
import requests
1513

16-
from labelbox import Client, Dataset
14+
from labelbox import Dataset
1715
from labelbox import LabelingFrontend
1816
from labelbox import OntologyBuilder, Tool, Option, Classification, MediaType
1917
from labelbox.orm import query
2018
from labelbox.pagination import PaginatedCollection
2119
from labelbox.schema.annotation_import import LabelImport
2220
from labelbox.schema.enums import AnnotationImportState
2321
from labelbox.schema.invite import Invite
24-
from labelbox.schema.project import Project
2522
from labelbox.schema.quality_mode import QualityMode
2623
from labelbox.schema.queue_mode import QueueMode
2724
from labelbox.schema.user import User
25+
from support.integration_client import Environ, IntegrationClient, EphemeralClient, AdminClient
2826

2927
IMG_URL = "https://picsum.photos/200/300.jpg"
3028
SMALL_DATASET_URL = "https://storage.googleapis.com/lb-artifacts-testing-public/sdk_integration_test/potato.jpeg"
3129
DATA_ROW_PROCESSING_WAIT_TIMEOUT_SECONDS = 30
3230
DATA_ROW_PROCESSING_WAIT_SLEEP_INTERNAL_SECONDS = 3
3331

3432

35-
class Environ(Enum):
36-
LOCAL = 'local'
37-
PROD = 'prod'
38-
STAGING = 'staging'
39-
ONPREM = 'onprem'
40-
CUSTOM = 'custom'
41-
STAGING_EU = 'staging-eu'
42-
EPHEMERAL = 'ephemeral' # Used for testing PRs with ephemeral environments
43-
44-
45-
EPHEMERAL_BASE_URL = "http://lb-api-public"
46-
47-
4833
@pytest.fixture(scope="session")
4934
def environ() -> Environ:
5035
"""
@@ -60,69 +45,6 @@ def environ() -> Environ:
6045
raise Exception(f'Missing LABELBOX_TEST_ENVIRON in: {os.environ}')
6146

6247

63-
def graphql_url(environ: str) -> str:
64-
if environ == Environ.PROD:
65-
return 'https://api.labelbox.com/graphql'
66-
elif environ == Environ.STAGING:
67-
return 'https://api.lb-stage.xyz/graphql'
68-
elif environ == Environ.STAGING_EU:
69-
return 'https://api.eu-de.lb-stage.xyz/graphql'
70-
elif environ == Environ.ONPREM:
71-
hostname = os.environ.get('LABELBOX_TEST_ONPREM_HOSTNAME', None)
72-
if hostname is None:
73-
raise Exception(f"Missing LABELBOX_TEST_ONPREM_INSTANCE")
74-
return f"{hostname}/api/_gql"
75-
elif environ == Environ.CUSTOM:
76-
graphql_api_endpoint = os.environ.get(
77-
'LABELBOX_TEST_GRAPHQL_API_ENDPOINT')
78-
if graphql_api_endpoint is None:
79-
raise Exception(f"Missing LABELBOX_TEST_GRAPHQL_API_ENDPOINT")
80-
return graphql_api_endpoint
81-
elif environ == Environ.EPHEMERAL:
82-
return f"{EPHEMERAL_BASE_URL}/graphql"
83-
return 'http://host.docker.internal:8080/graphql'
84-
85-
86-
def rest_url(environ: str) -> str:
87-
if environ == Environ.PROD:
88-
return 'https://api.labelbox.com/api/v1'
89-
elif environ == Environ.STAGING:
90-
return 'https://api.lb-stage.xyz/api/v1'
91-
elif environ == Environ.STAGING_EU:
92-
return 'https://api.eu-de.lb-stage.xyz/api/v1'
93-
elif environ == Environ.CUSTOM:
94-
rest_api_endpoint = os.environ.get('LABELBOX_TEST_REST_API_ENDPOINT')
95-
if rest_api_endpoint is None:
96-
raise Exception(f"Missing LABELBOX_TEST_REST_API_ENDPOINT")
97-
return rest_api_endpoint
98-
elif environ == Environ.EPHEMERAL:
99-
return f"{EPHEMERAL_BASE_URL}/api/v1"
100-
return 'http://host.docker.internal:8080/api/v1'
101-
102-
103-
def admin_url(environ: str) -> Union[str, None]:
104-
if environ == Environ.EPHEMERAL:
105-
return f"{EPHEMERAL_BASE_URL}/admin/v1"
106-
107-
return 'http://host.docker.internal:8080/admin/v1'
108-
109-
110-
def testing_api_key(environ: str) -> str:
111-
if environ == Environ.PROD:
112-
return os.environ["LABELBOX_TEST_API_KEY_PROD"]
113-
elif environ == Environ.STAGING:
114-
return os.environ["LABELBOX_TEST_API_KEY_STAGING"]
115-
elif environ == Environ.STAGING_EU:
116-
return os.environ["LABELBOX_TEST_API_KEY_STAGING_EU"]
117-
elif environ == Environ.ONPREM:
118-
return os.environ["LABELBOX_TEST_API_KEY_ONPREM"]
119-
elif environ == Environ.CUSTOM:
120-
return os.environ["LABELBOX_TEST_API_KEY_CUSTOM"]
121-
elif environ == Environ.EPHEMERAL:
122-
return os.environ["LABELBOX_TEST_API_KEY_EPHEMERAL"]
123-
return os.environ["LABELBOX_TEST_API_KEY_LOCAL"]
124-
125-
12648
def cancel_invite(client, invite_id):
12749
"""
12850
Do not use. Only for testing.
@@ -172,121 +94,15 @@ def queries():
17294
get_invites=get_invites)
17395

17496

175-
class IntegrationClient(Client):
176-
177-
def __init__(self, environ: str) -> None:
178-
api_url = graphql_url(environ)
179-
api_key = testing_api_key(environ)
180-
rest_endpoint = rest_url(environ)
181-
self._admin_endpoint = admin_url(environ)
182-
183-
super().__init__(api_key,
184-
api_url,
185-
enable_experimental=True,
186-
rest_endpoint=rest_endpoint)
187-
self.queries = []
188-
189-
def execute(self, query=None, params=None, check_naming=True, **kwargs):
190-
if check_naming and query is not None:
191-
assert re.match(r"(?:query|mutation) \w+PyApi", query) is not None
192-
self.queries.append((query, params))
193-
return super().execute(query, params, **kwargs)
194-
195-
def create_organization(self) -> str:
196-
endpoint = f"{self._admin_endpoint}/organizations/"
197-
response = requests.post(
198-
endpoint,
199-
headers=self.headers,
200-
json={"name": f"Test Org {uuid.uuid4()}"},
201-
)
202-
if response.status_code != requests.codes.created:
203-
raise Exception("Failed to create ephemeral org, message: " +
204-
str(response.json()['message']))
205-
206-
return response.json()['id']
207-
208-
def create_user(self, organization_id) -> tuple[str, str]:
209-
endpoint = f"{self._admin_endpoint}/user-identities/"
210-
identity_id = f"e2e+{uuid.uuid4()}"
211-
212-
response = requests.post(
213-
endpoint,
214-
headers=self.headers,
215-
json={
216-
"identityId": identity_id,
217-
"email": "email@email.com",
218-
"name": f"tester{uuid.uuid4()}",
219-
"verificationStatus": "VERIFIED",
220-
},
221-
)
222-
if response.status_code != requests.codes.created:
223-
raise Exception("Failed to create ephemeral org, message: " +
224-
str(response.json()['message']))
225-
226-
user_identity_id = response.json()['identityId']
227-
228-
endpoint = f"{self._admin_endpoint}/organizations/{organization_id}/users/"
229-
response = requests.post(
230-
endpoint,
231-
headers=self.headers,
232-
json={
233-
"identityId": user_identity_id,
234-
"organizationRole": "Admin"
235-
},
236-
)
237-
if response.status_code != requests.codes.created:
238-
raise Exception("Failed to create ephemeral org, message: " +
239-
str(response.json()['message']))
240-
241-
user_id = response.json()['id']
242-
243-
endpoint = f"{self._admin_endpoint}/users/{user_id}/token"
244-
response = requests.get(
245-
endpoint,
246-
headers=self.headers,
247-
)
248-
if response.status_code != requests.codes.created:
249-
raise Exception("Failed to create ephemeral org, message: " +
250-
str(response.json()['message']))
251-
252-
token = response["token"]
253-
254-
return user_id, token
255-
256-
def create_api_key_for_user(self, user_token) -> str:
257-
key_name = f"test-key+{uuid.uuid4()}"
258-
query = """
259-
mutation CreateApiKey($name: String!) {
260-
createApiKey(data: {name: $name}) {
261-
id
262-
jwt
263-
__typename
264-
}
265-
}
266-
"""
267-
params = {"name": key_name}
268-
req = self._make_gql_request(query=query, params=params)
269-
270-
return req["createApiKey"]["jwt"]
271-
mutation_name = "deleteDataRowsByQuery"
272-
query = """mutation DeleteDataRowsByQueryPyApi($searchQueryInput: SearchServiceQueryInput!) {
273-
%s(where: {searchQuery: $searchQueryInput})
274-
{ taskId }
275-
}
276-
""" % (mutation_name)
277-
query_params = {
278-
"searchQueryInput": {
279-
"query": search_query,
280-
"scope": None
281-
}
282-
}
283-
284-
res = self.execute(query, query_params, error_log_key="errors")
285-
res = res[mutation_name]
97+
@pytest.fixture(scope="session")
98+
def admin_client(environ: str):
99+
return AdminClient(environ)
286100

287101

288102
@pytest.fixture(scope="session")
289103
def client(environ: str):
104+
if environ == Environ.EPHEMERAL:
105+
return EphemeralClient()
290106
return IntegrationClient(environ)
291107

292108

tests/integration/support/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)