Skip to content

Commit ca3f880

Browse files
authored
[PLT-1357] Vb/fixtures for feature schemas plt 1342 (#1766)
1 parent 50bfe9a commit ca3f880

File tree

5 files changed

+161
-111
lines changed

5 files changed

+161
-111
lines changed

.github/workflows/python-package-develop.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,18 @@ jobs:
3838
- python-version: 3.8
3939
api-key: STAGING_LABELBOX_API_KEY_2
4040
da-test-key: DA_GCP_LABELBOX_API_KEY
41-
# - python-version: 3.9
42-
# api-key: STAGING_LABELBOX_API_KEY_3
43-
# da-test-key: DA_GCP_LABELBOX_API_KEY
44-
# - python-version: "3.10"
45-
# api-key: STAGING_LABELBOX_API_KEY_4
46-
# da-test-key: DA_GCP_LABELBOX_API_KEY
47-
# - python-version: 3.11
48-
# api-key: STAGING_LABELBOX_API_KEY
49-
# da-test-key: DA_GCP_LABELBOX_API_KEY
50-
# - python-version: 3.12
51-
# api-key: STAGING_LABELBOX_API_KEY_5
52-
# da-test-key: DA_GCP_LABELBOX_API_KEY
41+
- python-version: 3.9
42+
api-key: STAGING_LABELBOX_API_KEY_3
43+
da-test-key: DA_GCP_LABELBOX_API_KEY
44+
- python-version: "3.10"
45+
api-key: STAGING_LABELBOX_API_KEY_4
46+
da-test-key: DA_GCP_LABELBOX_API_KEY
47+
- python-version: 3.11
48+
api-key: STAGING_LABELBOX_API_KEY
49+
da-test-key: DA_GCP_LABELBOX_API_KEY
50+
- python-version: 3.12
51+
api-key: STAGING_LABELBOX_API_KEY_5
52+
da-test-key: DA_GCP_LABELBOX_API_KEY
5353
uses: ./.github/workflows/python-package-shared.yml
5454
with:
5555
python-version: ${{ matrix.python-version }}

libs/labelbox/tests/integration/conftest.py

Lines changed: 117 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -342,32 +342,39 @@ def _upload_invalid_data_rows_for_dataset(dataset: Dataset):
342342

343343
return _upload_invalid_data_rows_for_dataset
344344

345+
345346
@pytest.fixture
346-
def prompt_response_generation_project_with_new_dataset(client: Client, rand_gen, request):
347+
def prompt_response_generation_project_with_new_dataset(client: Client,
348+
rand_gen, request):
347349
"""fixture is parametrize and needs project_type in request"""
348350
media_type = request.param
349-
prompt_response_project = client.create_prompt_response_generation_project(name=f"{media_type.value}-{rand_gen(str)}",
350-
dataset_name=f"{media_type.value}-{rand_gen(str)}",
351-
data_row_count=1,
352-
media_type=media_type)
353-
351+
prompt_response_project = client.create_prompt_response_generation_project(
352+
name=f"{media_type.value}-{rand_gen(str)}",
353+
dataset_name=f"{media_type.value}-{rand_gen(str)}",
354+
data_row_count=1,
355+
media_type=media_type)
356+
354357
yield prompt_response_project
355-
358+
356359
prompt_response_project.delete()
357360

361+
358362
@pytest.fixture
359-
def prompt_response_generation_project_with_dataset_id(client: Client, dataset, rand_gen, request):
363+
def prompt_response_generation_project_with_dataset_id(client: Client, dataset,
364+
rand_gen, request):
360365
"""fixture is parametrized and needs project_type in request"""
361366
media_type = request.param
362-
prompt_response_project = client.create_prompt_response_generation_project(name=f"{media_type.value}-{rand_gen(str)}",
363-
dataset_id=dataset.uid,
364-
data_row_count=1,
365-
media_type=media_type)
366-
367+
prompt_response_project = client.create_prompt_response_generation_project(
368+
name=f"{media_type.value}-{rand_gen(str)}",
369+
dataset_id=dataset.uid,
370+
data_row_count=1,
371+
media_type=media_type)
372+
367373
yield prompt_response_project
368-
374+
369375
prompt_response_project.delete()
370376

377+
371378
@pytest.fixture
372379
def response_creation_project(client: Client, rand_gen):
373380
project_name = f"response-creation-project-{rand_gen(str)}"
@@ -377,87 +384,105 @@ def response_creation_project(client: Client, rand_gen):
377384

378385
project.delete()
379386

380-
@pytest.fixture
387+
388+
@pytest.fixture
381389
def prompt_response_features(rand_gen):
382-
383-
prompt_text = PromptResponseClassification(class_type=PromptResponseClassification.Type.PROMPT,
384-
name=f"{rand_gen(str)}-prompt text")
385-
386-
response_radio = PromptResponseClassification(class_type=PromptResponseClassification.Type.RESPONSE_RADIO,
387-
name=f"{rand_gen(str)}-response radio classification",
388-
options=[
389-
ResponseOption(value=f"{rand_gen(str)}-first radio option answer"),
390-
ResponseOption(value=f"{rand_gen(str)}-second radio option answer"),
391-
])
392-
393-
response_checklist = PromptResponseClassification(class_type=PromptResponseClassification.Type.RESPONSE_CHECKLIST,
394-
name=f"{rand_gen(str)}-response checklist classification",
395-
options=[
396-
ResponseOption(value=f"{rand_gen(str)}-first checklist option answer"),
397-
ResponseOption(value=f"{rand_gen(str)}-second checklist option answer"),
398-
])
399-
400-
response_text_with_char = PromptResponseClassification(class_type=PromptResponseClassification.Type.RESPONSE_TEXT,
401-
name=f"{rand_gen(str)}-response text with character min and max",
402-
character_min = 1,
403-
character_max = 10)
404-
405-
response_text = PromptResponseClassification(class_type=PromptResponseClassification.Type.RESPONSE_TEXT,
406-
name=f"{rand_gen(str)}-response text")
407-
408-
nested_response_radio = PromptResponseClassification(class_type=PromptResponseClassification.Type.RESPONSE_RADIO,
409-
name=f"{rand_gen(str)}-nested response radio classification",
410-
options=[
411-
ResponseOption(f"{rand_gen(str)}-first_radio_answer",
412-
options=[
413-
PromptResponseClassification(
414-
class_type=PromptResponseClassification.Type.RESPONSE_RADIO,
415-
name=f"{rand_gen(str)}-sub_radio_question",
416-
options=[ResponseOption(f"{rand_gen(str)}-first_sub_radio_answer")])
417-
])
418-
])
390+
391+
prompt_text = PromptResponseClassification(
392+
class_type=PromptResponseClassification.Type.PROMPT,
393+
name=f"{rand_gen(str)}-prompt text")
394+
395+
response_radio = PromptResponseClassification(
396+
class_type=PromptResponseClassification.Type.RESPONSE_RADIO,
397+
name=f"{rand_gen(str)}-response radio classification",
398+
options=[
399+
ResponseOption(value=f"{rand_gen(str)}-first radio option answer"),
400+
ResponseOption(value=f"{rand_gen(str)}-second radio option answer"),
401+
])
402+
403+
response_checklist = PromptResponseClassification(
404+
class_type=PromptResponseClassification.Type.RESPONSE_CHECKLIST,
405+
name=f"{rand_gen(str)}-response checklist classification",
406+
options=[
407+
ResponseOption(
408+
value=f"{rand_gen(str)}-first checklist option answer"),
409+
ResponseOption(
410+
value=f"{rand_gen(str)}-second checklist option answer"),
411+
])
412+
413+
response_text_with_char = PromptResponseClassification(
414+
class_type=PromptResponseClassification.Type.RESPONSE_TEXT,
415+
name=f"{rand_gen(str)}-response text with character min and max",
416+
character_min=1,
417+
character_max=10)
418+
419+
response_text = PromptResponseClassification(
420+
class_type=PromptResponseClassification.Type.RESPONSE_TEXT,
421+
name=f"{rand_gen(str)}-response text")
422+
423+
nested_response_radio = PromptResponseClassification(
424+
class_type=PromptResponseClassification.Type.RESPONSE_RADIO,
425+
name=f"{rand_gen(str)}-nested response radio classification",
426+
options=[
427+
ResponseOption(
428+
f"{rand_gen(str)}-first_radio_answer",
429+
options=[
430+
PromptResponseClassification(
431+
class_type=PromptResponseClassification.Type.
432+
RESPONSE_RADIO,
433+
name=f"{rand_gen(str)}-sub_radio_question",
434+
options=[
435+
ResponseOption(
436+
f"{rand_gen(str)}-first_sub_radio_answer")
437+
])
438+
])
439+
])
419440
yield {
420441
"prompts": [prompt_text],
421-
"responses": [response_text, response_radio, response_checklist, response_text_with_char, nested_response_radio]
442+
"responses": [
443+
response_text, response_radio, response_checklist,
444+
response_text_with_char, nested_response_radio
445+
]
422446
}
423447

448+
424449
@pytest.fixture
425-
def prompt_response_ontology(client: Client, rand_gen, prompt_response_features, request):
450+
def prompt_response_ontology(client: Client, rand_gen, prompt_response_features,
451+
request):
426452
"""fixture is parametrize and needs project_type in request"""
427-
453+
428454
project_type = request.param
429455
if project_type == MediaType.LLMPromptCreation:
430456
ontology_builder = OntologyBuilder(
431-
tools=[],
432-
classifications=prompt_response_features["prompts"])
457+
tools=[], classifications=prompt_response_features["prompts"])
433458
elif project_type == MediaType.LLMPromptResponseCreation:
434459
ontology_builder = OntologyBuilder(
435460
tools=[],
436-
classifications=prompt_response_features["prompts"] + prompt_response_features["responses"])
461+
classifications=prompt_response_features["prompts"] +
462+
prompt_response_features["responses"])
437463
else:
438464
ontology_builder = OntologyBuilder(
439-
tools=[],
440-
classifications=prompt_response_features["responses"]
441-
)
442-
465+
tools=[], classifications=prompt_response_features["responses"])
466+
443467
ontology_name = f"prompt-response-{rand_gen(str)}"
444468

445469
if project_type in MediaType:
446-
ontology = client.create_ontology(
447-
ontology_name,
448-
ontology_builder.asdict(),
449-
media_type=project_type)
470+
ontology = client.create_ontology(ontology_name,
471+
ontology_builder.asdict(),
472+
media_type=project_type)
450473
else:
451474
ontology = client.create_ontology(
452475
ontology_name,
453476
ontology_builder.asdict(),
454477
media_type=MediaType.Text,
455-
ontology_kind=OntologyKind.ResponseCreation
456-
)
478+
ontology_kind=OntologyKind.ResponseCreation)
457479
yield ontology
458-
459-
featureSchemaIds = [feature["featureSchemaId"] for feature in ontology.normalized["classifications"]]
460-
480+
481+
featureSchemaIds = [
482+
feature["featureSchemaId"]
483+
for feature in ontology.normalized["classifications"]
484+
]
485+
461486
try:
462487
client.delete_unused_ontology(ontology.uid)
463488
for featureSchemaId in featureSchemaIds:
@@ -466,6 +491,24 @@ def prompt_response_ontology(client: Client, rand_gen, prompt_response_features,
466491
print(f"Failed to delete ontology {ontology.uid}: {str(e)}")
467492

468493

494+
@pytest.fixture
495+
def point():
496+
return Tool(
497+
tool=Tool.Type.POINT,
498+
name="name",
499+
color="#ff0000",
500+
)
501+
502+
503+
@pytest.fixture
504+
def feature_schema(client, point):
505+
created_feature_schema = client.upsert_feature_schema(point.asdict())
506+
507+
yield created_feature_schema
508+
client.delete_unused_feature_schema(
509+
created_feature_schema.normalized['featureSchemaId'])
510+
511+
469512
@pytest.fixture
470513
def chat_evaluation_ontology(client, rand_gen):
471514
ontology_name = f"test-chat-evaluation-ontology-{rand_gen(str)}"
@@ -682,13 +725,12 @@ def offline_conversational_data_row(initial_dataset):
682725

683726
return data_row
684727

728+
685729
@pytest.fixture
686730
def response_data_row(initial_dataset):
687-
text_asset = {
688-
"row_data": "response sample text"
689-
}
731+
text_asset = {"row_data": "response sample text"}
690732
data_row = initial_dataset.create_data_row(text_asset)
691-
733+
692734
return data_row
693735

694736

libs/labelbox/tests/integration/test_feature_schema.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,22 +86,12 @@ def test_throws_an_error_when_updating_not_existing_feature_schema(client):
8686
client.update_feature_schema_title("doesntexist", "new title")
8787

8888

89-
def test_creates_a_new_feature_schema(client):
90-
created_feature_schema = client.upsert_feature_schema(point.asdict())
89+
def test_creates_a_new_feature_schema(feature_schema):
90+
assert feature_schema.uid is not None
9191

92-
assert created_feature_schema.uid is not None
9392

94-
client.delete_unused_feature_schema(
95-
created_feature_schema.normalized['featureSchemaId'])
96-
97-
98-
def test_updates_a_feature_schema(client):
99-
tool = Tool(
100-
tool=Tool.Type.POINT,
101-
name="name",
102-
color="#ff0000",
103-
)
104-
created_feature_schema = client.upsert_feature_schema(tool.asdict())
93+
def test_updates_a_feature_schema(client, feature_schema):
94+
created_feature_schema = feature_schema
10595
tool_to_update = Tool(
10696
tool=Tool.Type.POINT,
10797
name="new name",

libs/labelbox/tests/integration/test_labeling_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def test_request_labeling_service_moe_project(
5656
) == LabelingServiceStatus.Requested
5757

5858

59-
def test_request_labeling_service_incomplete_requirements(project, ontology):
59+
def test_request_labeling_service_incomplete_requirements(ontology, project):
6060
labeling_service = project.get_labeling_service(
6161
) # project fixture is an Image type project
6262
with pytest.raises(ResourceNotFoundError,

libs/labelbox/tests/integration/test_ontology.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,16 +177,31 @@ def _get_attr_stringify_json(obj, attr):
177177
return value
178178

179179

180-
def test_feature_schema_create_read(client, rand_gen):
181-
name = f"test-root-schema-{rand_gen(str)}"
182-
feature_schema_cat_normalized = {
180+
@pytest.fixture
181+
def name_for_read(rand_gen):
182+
yield f"test-root-schema-{rand_gen(str)}"
183+
184+
185+
@pytest.fixture
186+
def feature_schema_cat_normalized(name_for_read):
187+
yield {
183188
'tool': 'polygon',
184-
'name': name,
189+
'name': name_for_read,
185190
'color': 'black',
186191
'classifications': [],
187192
}
188-
created_feature_schema = client.create_feature_schema(
189-
feature_schema_cat_normalized)
193+
194+
195+
@pytest.fixture
196+
def feature_schema_for_read(client, feature_schema_cat_normalized):
197+
feature_schema = client.create_feature_schema(feature_schema_cat_normalized)
198+
yield feature_schema
199+
client.delete_unused_feature_schema(feature_schema.uid)
200+
201+
202+
def test_feature_schema_create_read(client, feature_schema_for_read,
203+
name_for_read):
204+
created_feature_schema = feature_schema_for_read
190205
queried_feature_schema = client.get_feature_schema(
191206
created_feature_schema.uid)
192207
for attr in Entity.FeatureSchema.fields():
@@ -195,9 +210,9 @@ def test_feature_schema_create_read(client, rand_gen):
195210
queried_feature_schema, attr)
196211

197212
time.sleep(3) # Slight delay for searching
198-
queried_feature_schemas = list(client.get_feature_schemas(name))
213+
queried_feature_schemas = list(client.get_feature_schemas(name_for_read))
199214
assert [feature_schema.name for feature_schema in queried_feature_schemas
200-
] == [name]
215+
] == [name_for_read]
201216
queried_feature_schema = queried_feature_schemas[0]
202217

203218
for attr in Entity.FeatureSchema.fields():
@@ -206,7 +221,10 @@ def test_feature_schema_create_read(client, rand_gen):
206221
queried_feature_schema, attr)
207222

208223

209-
def test_ontology_create_read(client, rand_gen):
224+
def test_ontology_create_read(
225+
client,
226+
rand_gen,
227+
):
210228
ontology_name = f"test-ontology-{rand_gen(str)}"
211229
tool_name = f"test-ontology-tool-{rand_gen(str)}"
212230
feature_schema_cat_normalized = {

0 commit comments

Comments
 (0)