From b1078aafa4e39a48b7fddad42e7a99985be93009 Mon Sep 17 00:00:00 2001 From: Gabefire <33893811+Gabefire@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:54:58 -0500 Subject: [PATCH 1/8] Remove setup from SDK --- libs/labelbox/src/labelbox/schema/ontology.py | 14 ++++--- libs/labelbox/src/labelbox/schema/project.py | 28 ------------- libs/labelbox/tests/conftest.py | 39 ++++++++---------- libs/labelbox/tests/data/export/conftest.py | 41 ++++++++----------- libs/labelbox/tests/integration/conftest.py | 24 ++++------- .../tests/integration/test_project.py | 21 ++++++---- .../tests/integration/test_project_setup.py | 29 ------------- 7 files changed, 65 insertions(+), 131 deletions(-) diff --git a/libs/labelbox/src/labelbox/schema/ontology.py b/libs/labelbox/src/labelbox/schema/ontology.py index 1726b514c..c04e60faa 100644 --- a/libs/labelbox/src/labelbox/schema/ontology.py +++ b/libs/labelbox/src/labelbox/schema/ontology.py @@ -562,14 +562,18 @@ class OntologyBuilder: There are no required instantiation arguments. To create an ontology, use the asdict() method after fully building your - ontology within this class, and inserting it into project.setup() as the + ontology within this class, and inserting it into client.create_ontology() as the "labeling_frontend_options" parameter. Example: - builder = OntologyBuilder() - ... - frontend = list(client.get_labeling_frontends())[0] - project.setup(frontend, builder.asdict()) + >>> builder = OntologyBuilder() + >>> ... + >>> ontology = client.create_ontology( + >>> "Ontology from new features", + >>> ontology_builder.asdict(), + >>> media_type=lb.MediaType.Image, + >>> ) + >>> project.connect_ontology(ontology) attributes: tools: (list) diff --git a/libs/labelbox/src/labelbox/schema/project.py b/libs/labelbox/src/labelbox/schema/project.py index 5746e8011..d21e93192 100644 --- a/libs/labelbox/src/labelbox/schema/project.py +++ b/libs/labelbox/src/labelbox/schema/project.py @@ -694,34 +694,6 @@ def connect_ontology(self, ontology) -> None: timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") self.update(setup_complete=timestamp) - def setup(self, labeling_frontend, labeling_frontend_options) -> None: - """This method will associate default labeling frontend with the project and create an ontology based on labeling_frontend_options. - - Args: - labeling_frontend (LabelingFrontend): Do not use, this parameter is deprecated. We now associate the default labeling frontend with the project. - labeling_frontend_options (dict or str): Labeling frontend options, - a.k.a. project ontology. If given a `dict` it will be converted - to `str` using `json.dumps`. - """ - - warnings.warn("This method is deprecated use connect_ontology instead.") - if labeling_frontend is not None: - warnings.warn( - "labeling_frontend parameter will not be used to create a new labeling frontend." - ) - - if self.is_chat_evaluation() or self.is_prompt_response(): - warnings.warn(""" - This project is a live chat evaluation project or prompt and response generation project. - Editor was setup automatically. - """) - return - - self._connect_default_labeling_front_end(labeling_frontend_options) - - timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") - self.update(setup_complete=timestamp) - def _connect_default_labeling_front_end(self, ontology_as_dict: dict): labeling_frontend = self.labeling_frontend() if ( diff --git a/libs/labelbox/tests/conftest.py b/libs/labelbox/tests/conftest.py index d25544034..c05bc6340 100644 --- a/libs/labelbox/tests/conftest.py +++ b/libs/labelbox/tests/conftest.py @@ -703,20 +703,19 @@ def create_label(): return label -def _setup_ontology(project): - editor = list( - project.client.get_labeling_frontends( - where=LabelingFrontend.name == "editor" - ) - )[0] +def _setup_ontology(project: Project, client: Client): ontology_builder = OntologyBuilder( tools=[ Tool(tool=Tool.Type.BBOX, name="test-bbox-class"), ] ) - project.setup(editor, ontology_builder.asdict()) - # TODO: ontology may not be synchronous after setup. remove sleep when api is more consistent - time.sleep(2) + ontology = client.create_ontology( + name="ontology with features", + media_type=MediaType.Image, + normalized=ontology_builder.asdict(), + ) + project.connect_ontology(ontology) + return OntologyBuilder.from_project(project) @@ -749,7 +748,6 @@ def configured_batch_project_with_label( """ project = client.create_project( name=rand_gen(str), - queue_mode=QueueMode.Batch, media_type=MediaType.Image, ) data_rows = [dr.uid for dr in list(dataset.data_rows())] @@ -784,7 +782,6 @@ def configured_batch_project_with_multiple_datarows( """ project = client.create_project( name=rand_gen(str), - queue_mode=QueueMode.Batch, media_type=MediaType.Image, ) global_keys = [dr.global_key for dr in data_rows] @@ -1048,14 +1045,12 @@ def configured_project( @pytest.fixture -def project_with_empty_ontology(project): - editor = list( - project.client.get_labeling_frontends( - where=LabelingFrontend.name == "editor" - ) - )[0] +def project_with_empty_ontology(project, client): empty_ontology = {"tools": [], "classifications": []} - project.setup(editor, empty_ontology) + ontology = client.create_ontology( + "empty ontology", MediaType.Image, empty_ontology + ) + project.connect_ontology(ontology) yield project @@ -1065,7 +1060,6 @@ def configured_project_with_complex_ontology( ): project = client.create_project( name=rand_gen(str), - queue_mode=QueueMode.Batch, media_type=MediaType.Image, ) dataset = initial_dataset @@ -1091,7 +1085,6 @@ def configured_project_with_complex_ontology( Tool(tool=Tool.Type.LINE, name="test-line-class"), Tool(tool=Tool.Type.POINT, name="test-point-class"), Tool(tool=Tool.Type.POLYGON, name="test-polygon-class"), - Tool(tool=Tool.Type.NER, name="test-ner-class"), ] options = [ @@ -1123,7 +1116,11 @@ def configured_project_with_complex_ontology( for c in classifications: ontology.add_classification(c) - project.setup(editor, ontology.asdict()) + ontology = client.create_ontology( + "complex image ontology", MediaType.Image, ontology.asdict() + ) + + project.connect_ontology(ontology) yield [project, data_row] teardown_helpers.teardown_project_labels_ontology_feature_schemas(project) diff --git a/libs/labelbox/tests/data/export/conftest.py b/libs/labelbox/tests/data/export/conftest.py index 0a62f39c8..0e1cb9536 100644 --- a/libs/labelbox/tests/data/export/conftest.py +++ b/libs/labelbox/tests/data/export/conftest.py @@ -1,5 +1,6 @@ import uuid import time +from labelbox.schema.media_type import MediaType import pytest from labelbox.schema.queue_mode import QueueMode from labelbox.schema.labeling_frontend import LabelingFrontend @@ -7,7 +8,7 @@ @pytest.fixture -def ontology(): +def ontology(client): bbox_tool_with_nested_text = { "required": False, "name": "bbox_tool_with_nested_text", @@ -193,13 +194,6 @@ def ontology(): }, ], } - named_entity = { - "tool": "named-entity", - "name": "named-entity", - "required": False, - "color": "#A30059", - "classifications": [], - } tools = [ bbox_tool, @@ -207,19 +201,20 @@ def ontology(): polygon_tool, polyline_tool, point_tool, - entity_tool, segmentation_tool, raster_segmentation_tool, - named_entity, ] classifications = [ checklist, - checklist_index, free_form_text, - free_form_text_index, radio, ] - return {"tools": tools, "classifications": classifications} + ontology = client.create_ontology( + "image ontology", + MediaType.Image, + {"tools": tools, "classifications": classifications}, + ) + return ontology @pytest.fixture @@ -246,15 +241,16 @@ def configured_project_with_ontology( dataset = initial_dataset project = client.create_project( name=rand_gen(str), - queue_mode=QueueMode.Batch, ) - editor = list( - client.get_labeling_frontends(where=LabelingFrontend.name == "editor") - )[0] - project.setup(editor, ontology) + project.connect_ontology(ontology) data_row_ids = [] - for _ in range(len(ontology["tools"]) + len(ontology["classifications"])): + normalized_ontology = ontology.normalized() + + for _ in range( + len(normalized_ontology["tools"]) + + len(normalized_ontology["classifications"]) + ): data_row_ids.append(dataset.create_data_row(row_data=image_url).uid) project.create_batch( rand_gen(str), @@ -273,12 +269,9 @@ def configured_project_without_data_rows( project = client.create_project( name=rand_gen(str), description=rand_gen(str), - queue_mode=QueueMode.Batch, ) - editor = list( - client.get_labeling_frontends(where=LabelingFrontend.name == "editor") - )[0] - project.setup(editor, ontology) + + project.connect_ontology(ontology) yield project teardown_helpers.teardown_project_labels_ontology_feature_schemas(project) diff --git a/libs/labelbox/tests/integration/conftest.py b/libs/labelbox/tests/integration/conftest.py index c917a6164..744ec385d 100644 --- a/libs/labelbox/tests/integration/conftest.py +++ b/libs/labelbox/tests/integration/conftest.py @@ -80,14 +80,12 @@ def project_pack(client): @pytest.fixture -def project_with_empty_ontology(project): - editor = list( - project.client.get_labeling_frontends( - where=LabelingFrontend.name == "editor" - ) - )[0] +def project_with_empty_ontology(project, client): empty_ontology = {"tools": [], "classifications": []} - project.setup(editor, empty_ontology) + ontology = client.create_ontology( + "empty ontology", MediaType.Image, empty_ontology + ) + project.connect_ontology(ontology) yield project @@ -131,19 +129,12 @@ def configured_project_with_complex_ontology( ) project.data_row_ids = data_row_ids - editor = list( - project.client.get_labeling_frontends( - where=LabelingFrontend.name == "editor" - ) - )[0] - ontology = OntologyBuilder() tools = [ Tool(tool=Tool.Type.BBOX, name="test-bbox-class"), Tool(tool=Tool.Type.LINE, name="test-line-class"), Tool(tool=Tool.Type.POINT, name="test-point-class"), Tool(tool=Tool.Type.POLYGON, name="test-polygon-class"), - Tool(tool=Tool.Type.NER, name="test-ner-class"), ] options = [ @@ -175,7 +166,10 @@ def configured_project_with_complex_ontology( for c in classifications: ontology.add_classification(c) - project.setup(editor, ontology.asdict()) + ontology = client.create_ontology( + "image ontology", MediaType.Image, ontology.asdict() + ) + project.connect_ontology(ontology) yield [project, data_row] teardown_helpers.teardown_project_labels_ontology_feature_schemas(project) diff --git a/libs/labelbox/tests/integration/test_project.py b/libs/labelbox/tests/integration/test_project.py index 6f0f74e35..b1014650c 100644 --- a/libs/labelbox/tests/integration/test_project.py +++ b/libs/labelbox/tests/integration/test_project.py @@ -2,6 +2,7 @@ import time import uuid +from labelbox.schema.ontology import OntologyBuilder, Tool import pytest import requests from lbox.exceptions import InvalidQueryError @@ -140,10 +141,6 @@ def test_extend_reservations(project): project.extend_reservations("InvalidQueueType") -@pytest.mark.skipif( - condition=os.environ["LABELBOX_TEST_ENVIRON"] == "onprem", - reason="new mutation does not work for onprem", -) def test_attach_instructions(client, project): with pytest.raises(ValueError) as execinfo: project.upsert_instructions("tests/integration/media/sample_pdf.pdf") @@ -151,11 +148,17 @@ def test_attach_instructions(client, project): str(execinfo.value) == "Cannot attach instructions to a project that has not been set up." ) - editor = list( - client.get_labeling_frontends(where=LabelingFrontend.name == "editor") - )[0] - empty_ontology = {"tools": [], "classifications": []} - project.setup(editor, empty_ontology) + ontology_builder = OntologyBuilder( + tools=[ + Tool(tool=Tool.Type.BBOX, name="test-bbox-class"), + ] + ) + ontology = client.create_ontology( + name="ontology with features", + media_type=MediaType.Image, + normalized=ontology_builder.asdict(), + ) + project.connect_ontology(ontology) project.upsert_instructions("tests/integration/media/sample_pdf.pdf") time.sleep(3) diff --git a/libs/labelbox/tests/integration/test_project_setup.py b/libs/labelbox/tests/integration/test_project_setup.py index a09d0469d..a6fba03e0 100644 --- a/libs/labelbox/tests/integration/test_project_setup.py +++ b/libs/labelbox/tests/integration/test_project_setup.py @@ -24,35 +24,6 @@ def simple_ontology(): return {"tools": [], "classifications": classifications} -def test_project_setup(project) -> None: - client = project.client - labeling_frontends = list( - client.get_labeling_frontends(where=LabelingFrontend.name == "Editor") - ) - assert len(labeling_frontends) - labeling_frontend = labeling_frontends[0] - - time.sleep(3) - now = datetime.now().astimezone(timezone.utc) - - project.setup(labeling_frontend, simple_ontology()) - assert now - project.setup_complete <= timedelta(seconds=3) - assert now - project.last_activity_time <= timedelta(seconds=3) - - assert project.labeling_frontend() == labeling_frontend - options = list(project.labeling_frontend_options()) - assert len(options) == 1 - options = options[0] - # TODO ensure that LabelingFrontendOptions can be obtaind by ID - with pytest.raises(InvalidQueryError): - assert options.labeling_frontend() == labeling_frontend - assert options.project() == project - assert options.organization() == client.get_organization() - assert options.customization_options == json.dumps(simple_ontology()) - assert project.organization() == client.get_organization() - assert project.created_by() == client.get_user() - - def test_project_editor_setup(client, project, rand_gen): ontology_name = f"test_project_editor_setup_ontology_name-{rand_gen(str)}" ontology = client.create_ontology(ontology_name, simple_ontology()) From 8124d7a49b44a0a296647e76245362993de56ab9 Mon Sep 17 00:00:00 2001 From: Gabefire <33893811+Gabefire@users.noreply.github.com> Date: Tue, 24 Sep 2024 14:33:18 -0500 Subject: [PATCH 2/8] Added one tool to "empty" project --- libs/labelbox/tests/conftest.py | 5 ++++- libs/labelbox/tests/integration/conftest.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/labelbox/tests/conftest.py b/libs/labelbox/tests/conftest.py index c05bc6340..79739608b 100644 --- a/libs/labelbox/tests/conftest.py +++ b/libs/labelbox/tests/conftest.py @@ -1046,7 +1046,10 @@ def configured_project( @pytest.fixture def project_with_empty_ontology(project, client): - empty_ontology = {"tools": [], "classifications": []} + tools = [ + Tool(tool=Tool.Type.BBOX, name="test-bbox-class").asdict(), + ] + empty_ontology = {"tools": tools, "classifications": []} ontology = client.create_ontology( "empty ontology", MediaType.Image, empty_ontology ) diff --git a/libs/labelbox/tests/integration/conftest.py b/libs/labelbox/tests/integration/conftest.py index 744ec385d..9702d0bb3 100644 --- a/libs/labelbox/tests/integration/conftest.py +++ b/libs/labelbox/tests/integration/conftest.py @@ -81,7 +81,10 @@ def project_pack(client): @pytest.fixture def project_with_empty_ontology(project, client): - empty_ontology = {"tools": [], "classifications": []} + tools = [ + Tool(tool=Tool.Type.BBOX, name="test-bbox-class").asdict(), + ] + empty_ontology = {"tools": tools, "classifications": []} ontology = client.create_ontology( "empty ontology", MediaType.Image, empty_ontology ) From bdfa70dcf1d251f00006a7849b6697c727346b59 Mon Sep 17 00:00:00 2001 From: Gabefire <33893811+Gabefire@users.noreply.github.com> Date: Tue, 24 Sep 2024 14:58:57 -0500 Subject: [PATCH 3/8] Added missing setup parameter --- libs/labelbox/tests/conftest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/labelbox/tests/conftest.py b/libs/labelbox/tests/conftest.py index 79739608b..91c1bcffa 100644 --- a/libs/labelbox/tests/conftest.py +++ b/libs/labelbox/tests/conftest.py @@ -660,7 +660,7 @@ def configured_project_with_label( [data_row.uid], # sample of data row objects 5, # priority between 1(Highest) - 5(lowest) ) - ontology = _setup_ontology(project) + ontology = _setup_ontology(project, client) label = _create_label( project, data_row, ontology, wait_for_label_processing ) @@ -757,7 +757,7 @@ def configured_batch_project_with_label( project.create_batch("test-batch", data_rows) project.data_row_ids = data_rows - ontology = _setup_ontology(project) + ontology = _setup_ontology(project, client) label = _create_label( project, data_row, ontology, wait_for_label_processing ) @@ -789,7 +789,7 @@ def configured_batch_project_with_multiple_datarows( batch_name = f"batch {uuid.uuid4()}" project.create_batch(batch_name, global_keys=global_keys) - ontology = _setup_ontology(project) + ontology = _setup_ontology(project, client) for datarow in data_rows: _create_label(project, datarow, ontology, wait_for_label_processing) From 13b8244087e8ebf670214acc51d77858590420fb Mon Sep 17 00:00:00 2001 From: Gabefire <33893811+Gabefire@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:11:39 -0500 Subject: [PATCH 4/8] Removed bad Mediatype --- libs/labelbox/tests/data/export/conftest.py | 36 +++------------------ 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/libs/labelbox/tests/data/export/conftest.py b/libs/labelbox/tests/data/export/conftest.py index 0e1cb9536..2949917d4 100644 --- a/libs/labelbox/tests/data/export/conftest.py +++ b/libs/labelbox/tests/data/export/conftest.py @@ -1,6 +1,6 @@ import uuid import time -from labelbox.schema.media_type import MediaType +from labelbox import MediaType, Client import pytest from labelbox.schema.queue_mode import QueueMode from labelbox.schema.labeling_frontend import LabelingFrontend @@ -8,7 +8,7 @@ @pytest.fixture -def ontology(client): +def ontology(client: Client): bbox_tool_with_nested_text = { "required": False, "name": "bbox_tool_with_nested_text", @@ -124,13 +124,6 @@ def ontology(client): "color": "#006FA6", "classifications": [], } - segmentation_tool = { - "required": False, - "name": "segmentation--", - "tool": "superpixel", - "color": "#A30059", - "classifications": [], - } raster_segmentation_tool = { "required": False, "name": "segmentation_mask", @@ -149,18 +142,7 @@ def ontology(client): {"label": "optionN", "value": "optionn"}, ], } - checklist_index = { - "required": False, - "instructions": "checklist_index", - "name": "checklist_index", - "type": "checklist", - "scope": "index", - "options": [ - {"label": "option1_index", "value": "option1_index"}, - {"label": "option2_index", "value": "option2_index"}, - {"label": "optionN_index", "value": "optionn_index"}, - ], - } + free_form_text = { "required": False, "instructions": "text", @@ -168,14 +150,7 @@ def ontology(client): "type": "text", "options": [], } - free_form_text_index = { - "required": False, - "instructions": "text_index", - "name": "text_index", - "type": "text", - "scope": "index", - "options": [], - } + radio = { "required": False, "instructions": "radio", @@ -201,7 +176,6 @@ def ontology(client): polygon_tool, polyline_tool, point_tool, - segmentation_tool, raster_segmentation_tool, ] classifications = [ @@ -211,8 +185,8 @@ def ontology(client): ] ontology = client.create_ontology( "image ontology", - MediaType.Image, {"tools": tools, "classifications": classifications}, + MediaType.Image, ) return ontology From 8dd1a7b3a2e6bd1ca2618bae781ccbac5f2d65f1 Mon Sep 17 00:00:00 2001 From: Gabefire <33893811+Gabefire@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:25:33 -0500 Subject: [PATCH 5/8] Last bug --- libs/labelbox/tests/conftest.py | 14 ++++---------- libs/labelbox/tests/integration/conftest.py | 6 ++++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/libs/labelbox/tests/conftest.py b/libs/labelbox/tests/conftest.py index 91c1bcffa..fabb55fe5 100644 --- a/libs/labelbox/tests/conftest.py +++ b/libs/labelbox/tests/conftest.py @@ -1045,13 +1045,13 @@ def configured_project( @pytest.fixture -def project_with_empty_ontology(project, client): +def project_with_empty_ontology(project, client: Client): tools = [ Tool(tool=Tool.Type.BBOX, name="test-bbox-class").asdict(), ] empty_ontology = {"tools": tools, "classifications": []} ontology = client.create_ontology( - "empty ontology", MediaType.Image, empty_ontology + "empty ontology", empty_ontology, MediaType.Image ) project.connect_ontology(ontology) yield project @@ -1059,7 +1059,7 @@ def project_with_empty_ontology(project, client): @pytest.fixture def configured_project_with_complex_ontology( - client, initial_dataset, rand_gen, image_url, teardown_helpers + client: Client, initial_dataset, rand_gen, image_url, teardown_helpers ): project = client.create_project( name=rand_gen(str), @@ -1076,12 +1076,6 @@ def configured_project_with_complex_ontology( ) project.data_row_ids = data_row_ids - editor = list( - project.client.get_labeling_frontends( - where=LabelingFrontend.name == "editor" - ) - )[0] - ontology = OntologyBuilder() tools = [ Tool(tool=Tool.Type.BBOX, name="test-bbox-class"), @@ -1120,7 +1114,7 @@ def configured_project_with_complex_ontology( ontology.add_classification(c) ontology = client.create_ontology( - "complex image ontology", MediaType.Image, ontology.asdict() + "complex image ontology", ontology.asdict(), MediaType.Image ) project.connect_ontology(ontology) diff --git a/libs/labelbox/tests/integration/conftest.py b/libs/labelbox/tests/integration/conftest.py index 9702d0bb3..31dd66282 100644 --- a/libs/labelbox/tests/integration/conftest.py +++ b/libs/labelbox/tests/integration/conftest.py @@ -80,13 +80,15 @@ def project_pack(client): @pytest.fixture -def project_with_empty_ontology(project, client): +def project_with_empty_ontology(project, client: Client): tools = [ Tool(tool=Tool.Type.BBOX, name="test-bbox-class").asdict(), ] empty_ontology = {"tools": tools, "classifications": []} ontology = client.create_ontology( - "empty ontology", MediaType.Image, empty_ontology + "empty ontology", + empty_ontology, + MediaType.Image, ) project.connect_ontology(ontology) yield project From 8fb38167cb59a6cb1fc65b1a01573554c7c730e0 Mon Sep 17 00:00:00 2001 From: Gabefire <33893811+Gabefire@users.noreply.github.com> Date: Tue, 24 Sep 2024 21:16:16 -0500 Subject: [PATCH 6/8] Added video project ontology --- libs/labelbox/tests/conftest.py | 6 +- libs/labelbox/tests/data/export/conftest.py | 202 +++++++++++++++++- .../test_export_video_streamable.py | 4 +- libs/labelbox/tests/integration/conftest.py | 12 +- .../tests/integration/test_project.py | 10 +- 5 files changed, 211 insertions(+), 23 deletions(-) diff --git a/libs/labelbox/tests/conftest.py b/libs/labelbox/tests/conftest.py index fabb55fe5..8cb651157 100644 --- a/libs/labelbox/tests/conftest.py +++ b/libs/labelbox/tests/conftest.py @@ -1026,11 +1026,11 @@ def _upload_invalid_data_rows_for_dataset(dataset: Dataset): @pytest.fixture def configured_project( - project_with_empty_ontology, initial_dataset, rand_gen, image_url + project_with_one_feature_ontology, initial_dataset, rand_gen, image_url ): dataset = initial_dataset data_row_id = dataset.create_data_row(row_data=image_url).uid - project = project_with_empty_ontology + project = project_with_one_feature_ontology batch = project.create_batch( rand_gen(str), @@ -1045,7 +1045,7 @@ def configured_project( @pytest.fixture -def project_with_empty_ontology(project, client: Client): +def project_with_one_feature_ontology(project, client: Client): tools = [ Tool(tool=Tool.Type.BBOX, name="test-bbox-class").asdict(), ] diff --git a/libs/labelbox/tests/data/export/conftest.py b/libs/labelbox/tests/data/export/conftest.py index 2949917d4..03e38bd73 100644 --- a/libs/labelbox/tests/data/export/conftest.py +++ b/libs/labelbox/tests/data/export/conftest.py @@ -117,11 +117,174 @@ def ontology(client: Client): "color": "#008941", "classifications": [], } - entity_tool = { + raster_segmentation_tool = { + "required": False, + "name": "segmentation_mask", + "tool": "raster-segmentation", + "color": "#ff0000", + "classifications": [], + } + checklist = { + "required": False, + "instructions": "checklist", + "name": "checklist", + "type": "checklist", + "options": [ + {"label": "option1", "value": "option1"}, + {"label": "option2", "value": "option2"}, + {"label": "optionN", "value": "optionn"}, + ], + } + + free_form_text = { + "required": False, + "instructions": "text", + "name": "text", + "type": "text", + "options": [], + } + + radio = { + "required": False, + "instructions": "radio", + "name": "radio", + "type": "radio", + "options": [ + { + "label": "first_radio_answer", + "value": "first_radio_answer", + "options": [], + }, + { + "label": "second_radio_answer", + "value": "second_radio_answer", + "options": [], + }, + ], + } + + tools = [ + bbox_tool, + bbox_tool_with_nested_text, + polygon_tool, + polyline_tool, + point_tool, + raster_segmentation_tool, + ] + classifications = [ + checklist, + free_form_text, + radio, + ] + ontology = client.create_ontology( + "image ontology", + {"tools": tools, "classifications": classifications}, + MediaType.Image, + ) + return ontology + + +@pytest.fixture +def video_ontology(client: Client): + bbox_tool_with_nested_text = { + "required": False, + "name": "bbox_tool_with_nested_text", + "tool": "rectangle", + "color": "#a23030", + "classifications": [ + { + "required": False, + "instructions": "nested", + "name": "nested", + "type": "radio", + "options": [ + { + "label": "radio_option_1", + "value": "radio_value_1", + "options": [ + { + "required": False, + "instructions": "nested_checkbox", + "name": "nested_checkbox", + "type": "checklist", + "options": [ + { + "label": "nested_checkbox_option_1", + "value": "nested_checkbox_value_1", + "options": [], + }, + { + "label": "nested_checkbox_option_2", + "value": "nested_checkbox_value_2", + }, + ], + }, + { + "required": False, + "instructions": "nested_text", + "name": "nested_text", + "type": "text", + "options": [], + }, + ], + }, + ], + } + ], + } + + bbox_tool = { + "required": False, + "name": "bbox", + "tool": "rectangle", + "color": "#a23030", + "classifications": [ + { + "required": False, + "instructions": "nested", + "name": "nested", + "type": "radio", + "options": [ + { + "label": "radio_option_1", + "value": "radio_value_1", + "options": [ + { + "required": False, + "instructions": "nested_checkbox", + "name": "nested_checkbox", + "type": "checklist", + "options": [ + { + "label": "nested_checkbox_option_1", + "value": "nested_checkbox_value_1", + "options": [], + }, + { + "label": "nested_checkbox_option_2", + "value": "nested_checkbox_value_2", + }, + ], + } + ], + }, + ], + } + ], + } + + polyline_tool = { + "required": False, + "name": "polyline", + "tool": "line", + "color": "#FF4A46", + "classifications": [], + } + point_tool = { "required": False, - "name": "entity--", - "tool": "named-entity", - "color": "#006FA6", + "name": "point--", + "tool": "point", + "color": "#008941", "classifications": [], } raster_segmentation_tool = { @@ -142,6 +305,18 @@ def ontology(client: Client): {"label": "optionN", "value": "optionn"}, ], } + checklist_index = { + "required": False, + "instructions": "checklist_index", + "name": "checklist_index", + "type": "checklist", + "scope": "index", + "options": [ + {"label": "option1_index", "value": "option1_index"}, + {"label": "option2_index", "value": "option2_index"}, + {"label": "optionN_index", "value": "optionn_index"}, + ], + } free_form_text = { "required": False, @@ -173,12 +348,12 @@ def ontology(client: Client): tools = [ bbox_tool, bbox_tool_with_nested_text, - polygon_tool, polyline_tool, point_tool, raster_segmentation_tool, ] classifications = [ + checklist_index, checklist, free_form_text, radio, @@ -186,7 +361,7 @@ def ontology(client: Client): ontology = client.create_ontology( "image ontology", {"tools": tools, "classifications": classifications}, - MediaType.Image, + MediaType.Video, ) return ontology @@ -250,6 +425,21 @@ def configured_project_without_data_rows( teardown_helpers.teardown_project_labels_ontology_feature_schemas(project) +@pytest.fixture +def configured_video_project_without_data_rows( + client, video_ontology, rand_gen, teardown_helpers +): + project = client.create_project( + name=rand_gen(str), + description=rand_gen(str), + media_type=MediaType.Video, + ) + + project.connect_ontology(video_ontology) + yield project + teardown_helpers.teardown_project_labels_ontology_feature_schemas(project) + + @pytest.fixture def model_run_with_data_rows( client, diff --git a/libs/labelbox/tests/data/export/streamable/test_export_video_streamable.py b/libs/labelbox/tests/data/export/streamable/test_export_video_streamable.py index 28ef6e0cf..7fa2bd6f6 100644 --- a/libs/labelbox/tests/data/export/streamable/test_export_video_streamable.py +++ b/libs/labelbox/tests/data/export/streamable/test_export_video_streamable.py @@ -21,13 +21,13 @@ def org_id(self, client): def test_export( self, client, - configured_project_without_data_rows, + configured_video_project_without_data_rows, video_data, video_data_row, bbox_video_annotation_objects, rand_gen, ): - project = configured_project_without_data_rows + project = configured_video_project_without_data_rows project_id = project.uid labels = [] diff --git a/libs/labelbox/tests/integration/conftest.py b/libs/labelbox/tests/integration/conftest.py index 31dd66282..ec9c32cde 100644 --- a/libs/labelbox/tests/integration/conftest.py +++ b/libs/labelbox/tests/integration/conftest.py @@ -80,7 +80,7 @@ def project_pack(client): @pytest.fixture -def project_with_empty_ontology(project, client: Client): +def project_with_one_feature_ontology(project, client: Client): tools = [ Tool(tool=Tool.Type.BBOX, name="test-bbox-class").asdict(), ] @@ -96,11 +96,11 @@ def project_with_empty_ontology(project, client: Client): @pytest.fixture def configured_project( - project_with_empty_ontology, initial_dataset, rand_gen, image_url + project_with_one_feature_ontology, initial_dataset, rand_gen, image_url ): dataset = initial_dataset data_row_id = dataset.create_data_row(row_data=image_url).uid - project = project_with_empty_ontology + project = project_with_one_feature_ontology batch = project.create_batch( rand_gen(str), @@ -116,7 +116,7 @@ def configured_project( @pytest.fixture def configured_project_with_complex_ontology( - client, initial_dataset, rand_gen, image_url, teardown_helpers + client: Client, initial_dataset, rand_gen, image_url, teardown_helpers ): project = client.create_project( name=rand_gen(str), @@ -172,7 +172,9 @@ def configured_project_with_complex_ontology( ontology.add_classification(c) ontology = client.create_ontology( - "image ontology", MediaType.Image, ontology.asdict() + "image ontology", + ontology.asdict(), + MediaType.Image, ) project.connect_ontology(ontology) diff --git a/libs/labelbox/tests/integration/test_project.py b/libs/labelbox/tests/integration/test_project.py index b1014650c..18b35152f 100644 --- a/libs/labelbox/tests/integration/test_project.py +++ b/libs/labelbox/tests/integration/test_project.py @@ -175,24 +175,20 @@ def test_attach_instructions(client, project): condition=os.environ["LABELBOX_TEST_ENVIRON"] == "onprem", reason="new mutation does not work for onprem", ) -def test_html_instructions(project_with_empty_ontology): +def test_html_instructions(project_with_one_feature_ontology): html_file_path = "/tmp/instructions.html" sample_html_str = "" with open(html_file_path, "w") as file: file.write(sample_html_str) - project_with_empty_ontology.upsert_instructions(html_file_path) - updated_ontology = project_with_empty_ontology.ontology().normalized + project_with_one_feature_ontology.upsert_instructions(html_file_path) + updated_ontology = project_with_one_feature_ontology.ontology().normalized instructions = updated_ontology.pop("projectInstructions") assert requests.get(instructions).text == sample_html_str -@pytest.mark.skipif( - condition=os.environ["LABELBOX_TEST_ENVIRON"] == "onprem", - reason="new mutation does not work for onprem", -) def test_same_ontology_after_instructions( configured_project_with_complex_ontology, ): From 54bbe61c078be34d93d1f52e148a12b8e810b531 Mon Sep 17 00:00:00 2001 From: Gabefire <33893811+Gabefire@users.noreply.github.com> Date: Tue, 24 Sep 2024 21:26:38 -0500 Subject: [PATCH 7/8] typo --- libs/labelbox/src/labelbox/schema/ontology.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/labelbox/src/labelbox/schema/ontology.py b/libs/labelbox/src/labelbox/schema/ontology.py index c04e60faa..48fc19f32 100644 --- a/libs/labelbox/src/labelbox/schema/ontology.py +++ b/libs/labelbox/src/labelbox/schema/ontology.py @@ -563,7 +563,7 @@ class OntologyBuilder: To create an ontology, use the asdict() method after fully building your ontology within this class, and inserting it into client.create_ontology() as the - "labeling_frontend_options" parameter. + "normalized" parameter. Example: >>> builder = OntologyBuilder() From a8e2d8cab074a315dea0b827e4269a844b6434b0 Mon Sep 17 00:00:00 2001 From: Gabefire <33893811+Gabefire@users.noreply.github.com> Date: Thu, 26 Sep 2024 10:28:30 -0500 Subject: [PATCH 8/8] Fixed tests --- libs/labelbox/tests/data/export/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/labelbox/tests/data/export/conftest.py b/libs/labelbox/tests/data/export/conftest.py index 8c7876366..b1b81230e 100644 --- a/libs/labelbox/tests/data/export/conftest.py +++ b/libs/labelbox/tests/data/export/conftest.py @@ -396,7 +396,7 @@ def configured_project_with_ontology( project.connect_ontology(ontology) data_row_ids = [] - normalized_ontology = ontology.normalized() + normalized_ontology = ontology.normalized for _ in range( len(normalized_ontology["tools"])