Skip to content

Commit 1142435

Browse files
authored
[PLT-1154] Vb/refactor project inputs plt 1154 (#1844)
1 parent 29e1567 commit 1142435

16 files changed

+297
-308
lines changed

libs/labelbox/src/labelbox/client.py

Lines changed: 126 additions & 185 deletions
Large diffs are not rendered by default.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
from typing import Optional, Set
2+
3+
from pydantic import BaseModel, ConfigDict, Field, model_validator
4+
from typing_extensions import Annotated
5+
6+
from labelbox.schema.media_type import MediaType
7+
from labelbox.schema.ontology_kind import EditorTaskType
8+
from labelbox.schema.quality_mode import (
9+
BENCHMARK_AUTO_AUDIT_NUMBER_OF_LABELS,
10+
BENCHMARK_AUTO_AUDIT_PERCENTAGE,
11+
CONSENSUS_AUTO_AUDIT_NUMBER_OF_LABELS,
12+
CONSENSUS_AUTO_AUDIT_PERCENTAGE,
13+
QualityMode,
14+
)
15+
from labelbox.schema.queue_mode import QueueMode
16+
17+
PositiveInt = Annotated[int, Field(gt=0)]
18+
19+
20+
class _CoreProjectInput(BaseModel):
21+
name: str
22+
description: Optional[str] = None
23+
media_type: MediaType
24+
queue_mode: QueueMode = Field(default=QueueMode.Batch, frozen=True)
25+
auto_audit_percentage: Optional[float] = None
26+
auto_audit_number_of_labels: Optional[int] = None
27+
quality_modes: Optional[Set[QualityMode]] = Field(
28+
default={QualityMode.Benchmark, QualityMode.Consensus}, exclude=True
29+
)
30+
is_benchmark_enabled: Optional[bool] = None
31+
is_consensus_enabled: Optional[bool] = None
32+
dataset_name_or_id: Optional[str] = None
33+
append_to_existing_dataset: Optional[bool] = None
34+
data_row_count: Optional[PositiveInt] = None
35+
editor_task_type: Optional[EditorTaskType] = None
36+
37+
model_config = ConfigDict(extra="forbid")
38+
39+
@model_validator(mode="after")
40+
def validate_fields(self):
41+
if (
42+
self.auto_audit_percentage is not None
43+
or self.auto_audit_number_of_labels is not None
44+
):
45+
raise ValueError(
46+
"quality_modes must be set instead of auto_audit_percentage or auto_audit_number_of_labels."
47+
)
48+
49+
if not self.name.strip():
50+
raise ValueError("project name must be a valid string.")
51+
52+
if self.quality_modes == {
53+
QualityMode.Benchmark,
54+
QualityMode.Consensus,
55+
}:
56+
self._set_quality_mode_attributes(
57+
CONSENSUS_AUTO_AUDIT_NUMBER_OF_LABELS,
58+
CONSENSUS_AUTO_AUDIT_PERCENTAGE,
59+
is_benchmark_enabled=True,
60+
is_consensus_enabled=True,
61+
)
62+
elif self.quality_modes == {QualityMode.Benchmark}:
63+
self._set_quality_mode_attributes(
64+
BENCHMARK_AUTO_AUDIT_NUMBER_OF_LABELS,
65+
BENCHMARK_AUTO_AUDIT_PERCENTAGE,
66+
is_benchmark_enabled=True,
67+
)
68+
elif self.quality_modes == {QualityMode.Consensus}:
69+
self._set_quality_mode_attributes(
70+
number_of_labels=CONSENSUS_AUTO_AUDIT_NUMBER_OF_LABELS,
71+
percentage=CONSENSUS_AUTO_AUDIT_PERCENTAGE,
72+
is_consensus_enabled=True,
73+
)
74+
75+
return self
76+
77+
def _set_quality_mode_attributes(
78+
self,
79+
number_of_labels,
80+
percentage,
81+
is_benchmark_enabled=False,
82+
is_consensus_enabled=False,
83+
):
84+
self.auto_audit_number_of_labels = number_of_labels
85+
self.auto_audit_percentage = percentage
86+
self.is_benchmark_enabled = is_benchmark_enabled
87+
self.is_consensus_enabled = is_consensus_enabled

libs/labelbox/src/labelbox/schema/ontology_kind.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def evaluate_ontology_kind_with_media_type(
5353
return media_type
5454

5555

56-
class EditorTaskType(Enum):
56+
class EditorTaskType(str, Enum):
5757
ModelChatEvaluation = "MODEL_CHAT_EVALUATION"
5858
ResponseCreation = "RESPONSE_CREATION"
5959
OfflineModelChatEvaluation = "OFFLINE_MODEL_CHAT_EVALUATION"

libs/labelbox/tests/conftest.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from labelbox.schema.ontology import Ontology
3333
from labelbox.schema.project import Project
3434
from labelbox.schema.quality_mode import QualityMode
35-
from labelbox.schema.queue_mode import QueueMode
3635

3736
IMG_URL = "https://picsum.photos/200/300.jpg"
3837
MASKABLE_IMG_URL = "https://storage.googleapis.com/labelbox-datasets/image_sample_data/2560px-Kitano_Street_Kobe01s5s4110.jpeg"
@@ -444,7 +443,6 @@ def conversation_entity_data_row(client, rand_gen):
444443
def project(client, rand_gen):
445444
project = client.create_project(
446445
name=rand_gen(str),
447-
queue_mode=QueueMode.Batch,
448446
media_type=MediaType.Image,
449447
)
450448
yield project
@@ -455,8 +453,7 @@ def project(client, rand_gen):
455453
def consensus_project(client, rand_gen):
456454
project = client.create_project(
457455
name=rand_gen(str),
458-
quality_mode=QualityMode.Consensus,
459-
queue_mode=QueueMode.Batch,
456+
quality_modes={QualityMode.Consensus},
460457
media_type=MediaType.Image,
461458
)
462459
yield project
@@ -646,7 +643,6 @@ def configured_project_with_label(
646643
"""
647644
project = client.create_project(
648645
name=rand_gen(str),
649-
queue_mode=QueueMode.Batch,
650646
media_type=MediaType.Image,
651647
)
652648
project._wait_until_data_rows_are_processed(
@@ -749,7 +745,6 @@ def configured_batch_project_with_label(
749745
"""
750746
project = client.create_project(
751747
name=rand_gen(str),
752-
queue_mode=QueueMode.Batch,
753748
media_type=MediaType.Image,
754749
)
755750
data_rows = [dr.uid for dr in list(dataset.data_rows())]
@@ -784,7 +779,6 @@ def configured_batch_project_with_multiple_datarows(
784779
"""
785780
project = client.create_project(
786781
name=rand_gen(str),
787-
queue_mode=QueueMode.Batch,
788782
media_type=MediaType.Image,
789783
)
790784
global_keys = [dr.global_key for dr in data_rows]
@@ -1065,7 +1059,6 @@ def configured_project_with_complex_ontology(
10651059
):
10661060
project = client.create_project(
10671061
name=rand_gen(str),
1068-
queue_mode=QueueMode.Batch,
10691062
media_type=MediaType.Image,
10701063
)
10711064
dataset = initial_dataset

libs/labelbox/tests/data/export/conftest.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import uuid
21
import time
2+
import uuid
3+
34
import pytest
4-
from labelbox.schema.queue_mode import QueueMode
5+
6+
from labelbox.schema.annotation_import import AnnotationImportState, LabelImport
57
from labelbox.schema.labeling_frontend import LabelingFrontend
6-
from labelbox.schema.annotation_import import LabelImport, AnnotationImportState
8+
from labelbox.schema.media_type import MediaType
79

810

911
@pytest.fixture
@@ -246,7 +248,7 @@ def configured_project_with_ontology(
246248
dataset = initial_dataset
247249
project = client.create_project(
248250
name=rand_gen(str),
249-
queue_mode=QueueMode.Batch,
251+
media_type=MediaType.Image,
250252
)
251253
editor = list(
252254
client.get_labeling_frontends(where=LabelingFrontend.name == "editor")
@@ -273,7 +275,24 @@ def configured_project_without_data_rows(
273275
project = client.create_project(
274276
name=rand_gen(str),
275277
description=rand_gen(str),
276-
queue_mode=QueueMode.Batch,
278+
media_type=MediaType.Image,
279+
)
280+
editor = list(
281+
client.get_labeling_frontends(where=LabelingFrontend.name == "editor")
282+
)[0]
283+
project.setup(editor, ontology)
284+
yield project
285+
teardown_helpers.teardown_project_labels_ontology_feature_schemas(project)
286+
287+
288+
@pytest.fixture
289+
def configured_video_project_without_data_rows(
290+
client, ontology, rand_gen, teardown_helpers
291+
):
292+
project = client.create_project(
293+
name=rand_gen(str),
294+
description=rand_gen(str),
295+
media_type=MediaType.Video,
277296
)
278297
editor = list(
279298
client.get_labeling_frontends(where=LabelingFrontend.name == "editor")

libs/labelbox/tests/data/export/streamable/test_export_video_streamable.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ def org_id(self, client):
2121
def test_export(
2222
self,
2323
client,
24-
configured_project_without_data_rows,
24+
configured_video_project_without_data_rows,
2525
video_data,
2626
video_data_row,
2727
bbox_video_annotation_objects,
2828
rand_gen,
2929
):
30-
project = configured_project_without_data_rows
30+
project = configured_video_project_without_data_rows
3131
project_id = project.uid
3232
labels = []
3333

libs/labelbox/tests/integration/conftest.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,40 @@
1-
from collections import defaultdict
2-
from itertools import islice
31
import json
42
import os
5-
import sys
63
import re
4+
import sys
75
import time
86
import uuid
9-
import requests
10-
from types import SimpleNamespace
11-
from typing import Type, List
7+
from collections import defaultdict
128
from enum import Enum
13-
from typing import Tuple
9+
from itertools import islice
10+
from types import SimpleNamespace
11+
from typing import List, Tuple, Type
1412

1513
import pytest
1614
import requests
1715

18-
from labelbox import Dataset, DataRow
19-
from labelbox import LabelingFrontend
2016
from labelbox import (
21-
OntologyBuilder,
22-
Tool,
23-
Option,
2417
Classification,
18+
Client,
19+
DataRow,
20+
Dataset,
21+
LabelingFrontend,
2522
MediaType,
23+
OntologyBuilder,
24+
Option,
2625
PromptResponseClassification,
2726
ResponseOption,
27+
Tool,
2828
)
2929
from labelbox.orm import query
3030
from labelbox.pagination import PaginatedCollection
3131
from labelbox.schema.annotation_import import LabelImport
3232
from labelbox.schema.catalog import Catalog
3333
from labelbox.schema.enums import AnnotationImportState
3434
from labelbox.schema.invite import Invite
35+
from labelbox.schema.ontology_kind import OntologyKind
3536
from labelbox.schema.quality_mode import QualityMode
36-
from labelbox.schema.queue_mode import QueueMode
3737
from labelbox.schema.user import User
38-
from labelbox import Client
39-
from labelbox.schema.ontology_kind import OntologyKind
4038

4139

4240
@pytest.fixture
@@ -69,7 +67,6 @@ def project_pack(client):
6967
projects = [
7068
client.create_project(
7169
name=f"user-proj-{idx}",
72-
queue_mode=QueueMode.Batch,
7370
media_type=MediaType.Image,
7471
)
7572
for idx in range(2)
@@ -117,7 +114,6 @@ def configured_project_with_complex_ontology(
117114
):
118115
project = client.create_project(
119116
name=rand_gen(str),
120-
queue_mode=QueueMode.Batch,
121117
media_type=MediaType.Image,
122118
)
123119
dataset = initial_dataset

libs/labelbox/tests/integration/test_client_errors.py

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import labelbox.client
1010
from labelbox import Project, User
11+
from labelbox.schema.media_type import MediaType
1112

1213

1314
def test_missing_api_key():
@@ -29,7 +30,7 @@ def test_bad_key(rand_gen):
2930
client = labelbox.client.Client(api_key=bad_key)
3031

3132
with pytest.raises(lbox.exceptions.AuthenticationError) as excinfo:
32-
client.create_project(name=rand_gen(str))
33+
client.create_project(name=rand_gen(str), media_type=MediaType.Image)
3334

3435

3536
def test_syntax_error(client):
@@ -77,31 +78,7 @@ def test_network_error(client):
7778
)
7879

7980
with pytest.raises(lbox.exceptions.NetworkError) as excinfo:
80-
client.create_project(name="Project name")
81-
82-
83-
def test_invalid_attribute_error(
84-
client,
85-
rand_gen,
86-
):
87-
# Creation
88-
with pytest.raises(lbox.exceptions.InvalidAttributeError) as excinfo:
89-
client.create_project(name="Name", invalid_field="Whatever")
90-
assert excinfo.value.db_object_type == Project
91-
assert excinfo.value.field == "invalid_field"
92-
93-
# Update
94-
project = client.create_project(name=rand_gen(str))
95-
with pytest.raises(lbox.exceptions.InvalidAttributeError) as excinfo:
96-
project.update(invalid_field="Whatever")
97-
assert excinfo.value.db_object_type == Project
98-
assert excinfo.value.field == "invalid_field"
99-
100-
# Top-level-fetch
101-
with pytest.raises(lbox.exceptions.InvalidAttributeError) as excinfo:
102-
client.get_projects(where=User.email == "email")
103-
assert excinfo.value.db_object_type == Project
104-
assert excinfo.value.field == {User.email}
81+
client.create_project(name="Project name", media_type=MediaType.Image)
10582

10683

10784
@pytest.mark.skip("timeouts cause failure before rate limit")

libs/labelbox/tests/integration/test_filtering.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from lbox.exceptions import InvalidQueryError
33

44
from labelbox import Project
5-
from labelbox.schema.queue_mode import QueueMode
5+
from labelbox.schema.media_type import MediaType
66

77

88
@pytest.fixture
@@ -11,9 +11,9 @@ def project_to_test_where(client, rand_gen):
1111
p_b_name = f"b-{rand_gen(str)}"
1212
p_c_name = f"c-{rand_gen(str)}"
1313

14-
p_a = client.create_project(name=p_a_name, queue_mode=QueueMode.Batch)
15-
p_b = client.create_project(name=p_b_name, queue_mode=QueueMode.Batch)
16-
p_c = client.create_project(name=p_c_name, queue_mode=QueueMode.Batch)
14+
p_a = client.create_project(name=p_a_name, media_type=MediaType.Image)
15+
p_b = client.create_project(name=p_b_name, media_type=MediaType.Image)
16+
p_c = client.create_project(name=p_c_name, media_type=MediaType.Image)
1717

1818
yield p_a, p_b, p_c
1919

0 commit comments

Comments
 (0)