From f7b47bdaa1d1263505a96c15814fc7cb286b31fa Mon Sep 17 00:00:00 2001 From: paulnoirel <87332996+paulnoirel@users.noreply.github.com> Date: Wed, 29 May 2024 15:54:26 +0100 Subject: [PATCH 1/4] Add example for project.clone() --- examples/basics/projects.ipynb | 457 +++++++++++++++++++++++++-------- 1 file changed, 345 insertions(+), 112 deletions(-) diff --git a/examples/basics/projects.ipynb b/examples/basics/projects.ipynb index 3bc3d8cb9..7cc50d9fa 100644 --- a/examples/basics/projects.ipynb +++ b/examples/basics/projects.ipynb @@ -1,18 +1,16 @@ { - "nbformat": 4, - "nbformat_minor": 5, - "metadata": {}, "cells": [ { + "cell_type": "markdown", "metadata": {}, "source": [ - "", - " ", + "\n", + " \n", "\n" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "\n", @@ -24,17 +22,17 @@ "\n", "" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "# Projects" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "* A project can be thought of as a specific labeling task on a set of labels\n", @@ -42,246 +40,418 @@ "* Each project has an ontology which defines the types of annotations supported during the labeling process\n", "**Note that there is a lot of advanced usage that is not covered in this notebook. See examples/project_configuration/project_setup.ipynb for those functions**\n", "* Also note that deprecated functions are not explained here." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "%pip install -q \"labelbox[data]\"", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "%pip install -q \"labelbox[data]\"" + ] }, { - "metadata": {}, - "source": "import labelbox as lb\nimport labelbox.types as lb_types\nfrom labelbox.schema.conflict_resolution_strategy import (\n ConflictResolutionStrategy,)\nimport uuid", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "import labelbox as lb\n", + "import labelbox.types as lb_types\n", + "from labelbox.schema.conflict_resolution_strategy import (\n", + " ConflictResolutionStrategy,)\n", + "import uuid" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "# API Key and Client\n", "Provide a valid api key below in order to properly connect to the Labelbox Client." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Add your API key\nAPI_KEY = \"\"\n# To get your API key go to: Workspace settings -> API -> Create API Key\nclient = lb.Client(api_key=API_KEY)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Add your API key\n", + "API_KEY = \"\"\n", + "# To get your API key go to: Workspace settings -> API -> Create API Key\n", + "client = lb.Client(api_key=API_KEY)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Create a project\n" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Creates an empty project\nproject = client.create_project(\n name=\"my-test-project\",\n description=\"a description\",\n media_type=lb.MediaType.Image,\n)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Creates an empty project\n", + "project = client.create_project(\n", + " name=\"my-test-project\",\n", + " description=\"a description\",\n", + " media_type=lb.MediaType.Image,\n", + ")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Create a dataset with data rows" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "dataset = client.create_dataset(name=\"project-demo-dataset\")\nglobal_keys = []\nuploads = []\n# Generate data rows\nfor i in range(1, 9):\n gb_key = \"TEST-ID-%id\" % uuid.uuid1()\n uploads.append({\n \"row_data\":\n f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n \"global_key\":\n gb_key,\n })\n global_keys.append(gb_key)\n\ntask = dataset.create_data_rows(uploads)\ntask.wait_till_done()\nprint(\"ERRORS: \", task.errors)\nprint(\"RESULT URL: \", task.result_url)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "dataset = client.create_dataset(name=\"project-demo-dataset\")\n", + "global_keys = []\n", + "uploads = []\n", + "# Generate data rows\n", + "for i in range(1, 9):\n", + " gb_key = \"TEST-ID-%id\" % uuid.uuid1()\n", + " uploads.append({\n", + " \"row_data\":\n", + " f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n", + " \"global_key\":\n", + " gb_key,\n", + " })\n", + " global_keys.append(gb_key)\n", + "\n", + "task = dataset.create_data_rows(uploads)\n", + "task.wait_till_done()\n", + "print(\"ERRORS: \", task.errors)\n", + "print(\"RESULT URL: \", task.result_url)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Add data rows to a project \n" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "project.create_batch(\n \"project-demo\", # each batch in a project must have a unique name\n global_keys=\n global_keys, # paginated collection of data row objects, list of data row ids or global keys\n priority=1, # priority between 1(highest) - 5(lowest)\n)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "project.create_batch(\n", + " \"project-demo\", # each batch in a project must have a unique name\n", + " global_keys=\n", + " global_keys, # paginated collection of data row objects, list of data row ids or global keys\n", + " priority=1, # priority between 1(highest) - 5(lowest)\n", + ")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Create tags and assign them to a project\n", "In this section, we are creating a tag in the ontology and associating it with a project. Then we are listing the tags attached to a project.\n" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Create a tag" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Get the organization\norganization = client.get_organization()\n\ntag = organization.create_resource_tag({\n \"text\": \"new-tag-name\",\n \"color\": \"4ed2f9\"\n})", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Get the organization\n", + "organization = client.get_organization()\n", + "\n", + "tag = organization.create_resource_tag({\n", + " \"text\": \"new-tag-name\",\n", + " \"color\": \"4ed2f9\"\n", + "})" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Assign the tag to a project" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "tags = project.update_project_resource_tags([tag.uid])", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "tags = project.update_project_resource_tags([tag.uid])" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Get project tags" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "tags = project.get_resource_tags()", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "tags = project.get_resource_tags()" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Attach ontology and label data rows\n", "\n", "In this section, we are creating an ontology to attach to a project and creating labels to import as ground truths. We need this setup to demonstrate other methods later in the demo. For more information, please reference our [Ontology](https://docs.labelbox.com/reference/ontology) and [Import Image Annotation](https://docs.labelbox.com/reference/import-image-annotations) development guides." - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Create your ontology" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Create normalized json with a radio classification\nontology_builder = lb.OntologyBuilder(\n classifications=[ # List of Classification objects\n lb.Classification(\n class_type=lb.Classification.Type.RADIO,\n name=\"radio_question\",\n options=[\n lb.Option(value=\"first_radio_answer\"),\n lb.Option(value=\"second_radio_answer\"),\n ],\n ),\n ])\n# Creating an ontology\nontology = client.create_ontology(\"test-ontology\", ontology_builder.asdict())", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null - }, - { + "source": [ + "# Create normalized json with a radio classification\n", + "ontology_builder = lb.OntologyBuilder(\n", + " classifications=[ # List of Classification objects\n", + " lb.Classification(\n", + " class_type=lb.Classification.Type.RADIO,\n", + " name=\"radio_question\",\n", + " options=[\n", + " lb.Option(value=\"first_radio_answer\"),\n", + " lb.Option(value=\"second_radio_answer\"),\n", + " ],\n", + " ),\n", + " ])\n", + "# Creating an ontology\n", + "ontology = client.create_ontology(\"test-ontology\", ontology_builder.asdict())" + ] + }, + { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Attach ontology to project" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "project.setup_editor(ontology)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "project.setup_editor(ontology)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Create labels and upload them to project as ground truths" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Create labels\nlabels = []\nfor global_key in global_keys:\n labels.append(\n lb_types.Label(\n data={\"global_key\": global_key},\n annotations=[\n # Create radio classification annotation for labels\n lb_types.ClassificationAnnotation(\n name=\"radio_question\",\n value=lb_types.Radio(answer=lb_types.ClassificationAnswer(\n name=\"second_radio_answer\")),\n )\n ],\n ))\n\n# Upload labels for the data rows in project\nupload_job = lb.LabelImport.create_from_objects(\n client=client,\n project_id=project.uid,\n name=\"label_import_job\" + str(uuid.uuid4()),\n labels=labels,\n)\n\nupload_job.wait_until_done()\n\nprint(f\"Errors: {upload_job.errors}\")", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Create labels\n", + "labels = []\n", + "for global_key in global_keys:\n", + " labels.append(\n", + " lb_types.Label(\n", + " data={\"global_key\": global_key},\n", + " annotations=[\n", + " # Create radio classification annotation for labels\n", + " lb_types.ClassificationAnnotation(\n", + " name=\"radio_question\",\n", + " value=lb_types.Radio(answer=lb_types.ClassificationAnswer(\n", + " name=\"second_radio_answer\")),\n", + " )\n", + " ],\n", + " ))\n", + "\n", + "# Upload labels for the data rows in project\n", + "upload_job = lb.LabelImport.create_from_objects(\n", + " client=client,\n", + " project_id=project.uid,\n", + " name=\"label_import_job\" + str(uuid.uuid4()),\n", + " labels=labels,\n", + ")\n", + "\n", + "upload_job.wait_until_done()\n", + "\n", + "print(f\"Errors: {upload_job.errors}\")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Move data rows in project to different task queues" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Get list of task queues for project\ntask_queues = project.task_queues()\n\nfor task_queue in task_queues:\n print(task_queue)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Get list of task queues for project\n", + "task_queues = project.task_queues()\n", + "\n", + "for task_queue in task_queues:\n", + " print(task_queue)" + ] }, { - "metadata": {}, - "source": "project.move_data_rows_to_task_queue(\n data_row_ids=lb.GlobalKeys(global_keys), # Provide a list of global keys\n task_queue_id=task_queues[2].\n uid, # Passing None moves data rows to \"Done\" task queue\n)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "project.move_data_rows_to_task_queue(\n", + " data_row_ids=lb.GlobalKeys(global_keys), # Provide a list of global keys\n", + " task_queue_id=task_queues[2].\n", + " uid, # Passing None moves data rows to \"Done\" task queue\n", + ")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Fetch project configuration" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Note the project is not fully setup many of the fields will be empty.\nprint(\"Project is not setup yet:\", project.setup_complete is None)\nprint(\"Project name:\", project.name)\nprint(\"Project description:\", project.description)\nprint(\"Media Type:\", project.media_type)\nbatches = [b for b in project.batches()]\nprint(\"Project Batches\", batches)\nprint(\"Ontology:\", project.ontology())", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Note the project is not fully setup many of the fields will be empty.\n", + "print(\"Project is not setup yet:\", project.setup_complete is None)\n", + "print(\"Project name:\", project.name)\n", + "print(\"Project description:\", project.description)\n", + "print(\"Media Type:\", project.media_type)\n", + "batches = [b for b in project.batches()]\n", + "print(\"Project Batches\", batches)\n", + "print(\"Ontology:\", project.ontology())" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Return number of labeled data rows" - ], - "cell_type": "markdown" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Number of labels:\", project.get_label_count())" + ] }, { + "cell_type": "markdown", + "id": "818feeea", "metadata": {}, - "source": "print(\"Number of labels:\", project.get_label_count())", + "source": [ + "### Duplicate a project\n", + "Please see the section [Duplicate a project](https://docs.labelbox.com/docs/create-a-project#duplicate-a-project) to have the scope of the method." + ] + }, + { "cell_type": "code", + "execution_count": null, + "id": "b01b2127", + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "destination_project_id = project.clone()\n", + "\n", + "destination_project = client.get_project(destination_project_id)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Copy labels and data rows from one project to a different project\n", "In the below steps we will be copying data rows with their corresponding labels from one project to a different project with a similar ontology. First, we must set up a new project with a ontology that matches the tooling of our source project ontology." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Create an empty destination project\ndestination_project = client.create_project(\n name=\"destination-test-project\",\n description=\"a description\",\n media_type=lb.MediaType.Image,\n)\n\n# Create ontology and attach to destination project\ndestination_ontology_builder = lb.OntologyBuilder(\n classifications=[ # List of Classification objects\n lb.Classification(\n class_type=lb.Classification.Type.RADIO,\n name=\"destination_radio_question\",\n options=[\n lb.Option(value=\"destination_first_radio_answer\"),\n lb.Option(value=\"destination_second_radio_answer\"),\n ],\n ),\n ])\n\ndestination_ontology = client.create_ontology(\"dest-test-ontology\",\n ontology_builder.asdict())\n\ndestination_project.setup_editor(destination_ontology)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Create an empty destination project\n", + "destination_project = client.create_project(\n", + " name=\"destination-test-project\",\n", + " description=\"a description\",\n", + " media_type=lb.MediaType.Image,\n", + ")\n", + "\n", + "# Create ontology and attach to destination project\n", + "destination_ontology_builder = lb.OntologyBuilder(\n", + " classifications=[ # List of Classification objects\n", + " lb.Classification(\n", + " class_type=lb.Classification.Type.RADIO,\n", + " name=\"destination_radio_question\",\n", + " options=[\n", + " lb.Option(value=\"destination_first_radio_answer\"),\n", + " lb.Option(value=\"destination_second_radio_answer\"),\n", + " ],\n", + " ),\n", + " ])\n", + "\n", + "destination_ontology = client.create_ontology(\"dest-test-ontology\",\n", + " ontology_builder.asdict())\n", + "\n", + "destination_project.setup_editor(destination_ontology)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Copy data rows and labels\n", @@ -306,36 +476,99 @@ " * ConflictResolutionStrategy.OverrideWithAnnotations\n", "* `param batch_priority`\n", " - The priority of the batch." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Get ontology dictionary to obtain featureSchemaIds\nsource_ontology_normalized = ontology.normalized\ndestination_ontology_normalized = destination_ontology.normalized\n\nANNOTATION_ONTOLOGY_MAPPING = {\n source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0]\n [\"featureSchemaId\"], # Classification featureSchemaID\n source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0][\"options\"][0]\n [\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0][\"options\"][1]\n [\"featureSchemaId\"],\n}", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Get ontology dictionary to obtain featureSchemaIds\n", + "source_ontology_normalized = ontology.normalized\n", + "destination_ontology_normalized = destination_ontology.normalized\n", + "\n", + "ANNOTATION_ONTOLOGY_MAPPING = {\n", + " source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:\n", + " destination_ontology_normalized[\"classifications\"][0]\n", + " [\"featureSchemaId\"], # Classification featureSchemaID\n", + " source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:\n", + " destination_ontology_normalized[\"classifications\"][0][\"options\"][0]\n", + " [\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n", + " source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:\n", + " destination_ontology_normalized[\"classifications\"][0][\"options\"][1]\n", + " [\"featureSchemaId\"],\n", + "}" + ] }, { - "metadata": {}, - "source": "send_to_annotate_params = {\n \"source_project_id\":\n project.uid,\n \"annotations_ontology_mapping\":\n ANNOTATION_ONTOLOGY_MAPPING,\n \"exclude_data_rows_in_project\":\n False,\n \"override_existing_annotations_rule\":\n ConflictResolutionStrategy.OverrideWithPredictions,\n \"batch_priority\":\n 5,\n}\n\n# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels.\nqueue_id = [\n queue.uid\n for queue in destination_project.task_queues()\n if queue.queue_type == \"MANUAL_REVIEW_QUEUE\"\n][0]\n\ntask = client.send_to_annotate_from_catalog(\n destination_project_id=destination_project.uid,\n task_queue_id=\n queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n batch_name=\"Prediction Import Demo Batch\",\n data_rows=lb.GlobalKeys(\n global_keys # Provide a list of global keys from source project\n ),\n params=send_to_annotate_params,\n)\n\ntask.wait_till_done()\n\nprint(f\"Errors: {task.errors}\")", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "send_to_annotate_params = {\n", + " \"source_project_id\":\n", + " project.uid,\n", + " \"annotations_ontology_mapping\":\n", + " ANNOTATION_ONTOLOGY_MAPPING,\n", + " \"exclude_data_rows_in_project\":\n", + " False,\n", + " \"override_existing_annotations_rule\":\n", + " ConflictResolutionStrategy.OverrideWithPredictions,\n", + " \"batch_priority\":\n", + " 5,\n", + "}\n", + "\n", + "# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels.\n", + "queue_id = [\n", + " queue.uid\n", + " for queue in destination_project.task_queues()\n", + " if queue.queue_type == \"MANUAL_REVIEW_QUEUE\"\n", + "][0]\n", + "\n", + "task = client.send_to_annotate_from_catalog(\n", + " destination_project_id=destination_project.uid,\n", + " task_queue_id=\n", + " queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n", + " batch_name=\"Prediction Import Demo Batch\",\n", + " data_rows=lb.GlobalKeys(\n", + " global_keys # Provide a list of global keys from source project\n", + " ),\n", + " params=send_to_annotate_params,\n", + ")\n", + "\n", + "task.wait_till_done()\n", + "\n", + "print(f\"Errors: {task.errors}\")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Clean Up" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# project.delete()\n# destination_project.delete()\n# dataset.delete()\n# client.delete_unused_ontology(destination_ontology.uid)\n# client.delete_unused_ontology(ontology.uid)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# project.delete()\n", + "# destination_project.delete()\n", + "# dataset.delete()\n", + "# client.delete_unused_ontology(destination_ontology.uid)\n", + "# client.delete_unused_ontology(ontology.uid)" + ] } - ] -} \ No newline at end of file + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From bf9c113d03c7943b9572402af508f28b0544c6a2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 29 May 2024 14:55:50 +0000 Subject: [PATCH 2/4] :art: Cleaned --- examples/basics/projects.ipynb | 454 +++++++++------------------------ 1 file changed, 118 insertions(+), 336 deletions(-) diff --git a/examples/basics/projects.ipynb b/examples/basics/projects.ipynb index 7cc50d9fa..df78ea04a 100644 --- a/examples/basics/projects.ipynb +++ b/examples/basics/projects.ipynb @@ -1,16 +1,18 @@ { + "nbformat": 4, + "nbformat_minor": 5, + "metadata": {}, "cells": [ { - "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - " \n", + "", + " ", "\n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "\n", @@ -22,17 +24,17 @@ "\n", "" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "# Projects" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "* A project can be thought of as a specific labeling task on a set of labels\n", @@ -40,418 +42,261 @@ "* Each project has an ontology which defines the types of annotations supported during the labeling process\n", "**Note that there is a lot of advanced usage that is not covered in this notebook. See examples/project_configuration/project_setup.ipynb for those functions**\n", "* Also note that deprecated functions are not explained here." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "%pip install -q \"labelbox[data]\"", + "cell_type": "code", "outputs": [], - "source": [ - "%pip install -q \"labelbox[data]\"" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "import labelbox as lb\nimport labelbox.types as lb_types\nfrom labelbox.schema.conflict_resolution_strategy import (\n ConflictResolutionStrategy,)\nimport uuid", + "cell_type": "code", "outputs": [], - "source": [ - "import labelbox as lb\n", - "import labelbox.types as lb_types\n", - "from labelbox.schema.conflict_resolution_strategy import (\n", - " ConflictResolutionStrategy,)\n", - "import uuid" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "# API Key and Client\n", "Provide a valid api key below in order to properly connect to the Labelbox Client." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Add your API key\nAPI_KEY = \"\"\n# To get your API key go to: Workspace settings -> API -> Create API Key\nclient = lb.Client(api_key=API_KEY)", + "cell_type": "code", "outputs": [], - "source": [ - "# Add your API key\n", - "API_KEY = \"\"\n", - "# To get your API key go to: Workspace settings -> API -> Create API Key\n", - "client = lb.Client(api_key=API_KEY)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Create a project\n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Creates an empty project\nproject = client.create_project(\n name=\"my-test-project\",\n description=\"a description\",\n media_type=lb.MediaType.Image,\n)", + "cell_type": "code", "outputs": [], - "source": [ - "# Creates an empty project\n", - "project = client.create_project(\n", - " name=\"my-test-project\",\n", - " description=\"a description\",\n", - " media_type=lb.MediaType.Image,\n", - ")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Create a dataset with data rows" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "dataset = client.create_dataset(name=\"project-demo-dataset\")\nglobal_keys = []\nuploads = []\n# Generate data rows\nfor i in range(1, 9):\n gb_key = \"TEST-ID-%id\" % uuid.uuid1()\n uploads.append({\n \"row_data\":\n f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n \"global_key\":\n gb_key,\n })\n global_keys.append(gb_key)\n\ntask = dataset.create_data_rows(uploads)\ntask.wait_till_done()\nprint(\"ERRORS: \", task.errors)\nprint(\"RESULT URL: \", task.result_url)", + "cell_type": "code", "outputs": [], - "source": [ - "dataset = client.create_dataset(name=\"project-demo-dataset\")\n", - "global_keys = []\n", - "uploads = []\n", - "# Generate data rows\n", - "for i in range(1, 9):\n", - " gb_key = \"TEST-ID-%id\" % uuid.uuid1()\n", - " uploads.append({\n", - " \"row_data\":\n", - " f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n", - " \"global_key\":\n", - " gb_key,\n", - " })\n", - " global_keys.append(gb_key)\n", - "\n", - "task = dataset.create_data_rows(uploads)\n", - "task.wait_till_done()\n", - "print(\"ERRORS: \", task.errors)\n", - "print(\"RESULT URL: \", task.result_url)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Add data rows to a project \n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "project.create_batch(\n \"project-demo\", # each batch in a project must have a unique name\n global_keys=\n global_keys, # paginated collection of data row objects, list of data row ids or global keys\n priority=1, # priority between 1(highest) - 5(lowest)\n)", + "cell_type": "code", "outputs": [], - "source": [ - "project.create_batch(\n", - " \"project-demo\", # each batch in a project must have a unique name\n", - " global_keys=\n", - " global_keys, # paginated collection of data row objects, list of data row ids or global keys\n", - " priority=1, # priority between 1(highest) - 5(lowest)\n", - ")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Create tags and assign them to a project\n", "In this section, we are creating a tag in the ontology and associating it with a project. Then we are listing the tags attached to a project.\n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Create a tag" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Get the organization\norganization = client.get_organization()\n\ntag = organization.create_resource_tag({\n \"text\": \"new-tag-name\",\n \"color\": \"4ed2f9\"\n})", + "cell_type": "code", "outputs": [], - "source": [ - "# Get the organization\n", - "organization = client.get_organization()\n", - "\n", - "tag = organization.create_resource_tag({\n", - " \"text\": \"new-tag-name\",\n", - " \"color\": \"4ed2f9\"\n", - "})" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Assign the tag to a project" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "tags = project.update_project_resource_tags([tag.uid])", + "cell_type": "code", "outputs": [], - "source": [ - "tags = project.update_project_resource_tags([tag.uid])" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Get project tags" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "tags = project.get_resource_tags()", + "cell_type": "code", "outputs": [], - "source": [ - "tags = project.get_resource_tags()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Attach ontology and label data rows\n", "\n", "In this section, we are creating an ontology to attach to a project and creating labels to import as ground truths. We need this setup to demonstrate other methods later in the demo. For more information, please reference our [Ontology](https://docs.labelbox.com/reference/ontology) and [Import Image Annotation](https://docs.labelbox.com/reference/import-image-annotations) development guides." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Create your ontology" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Create normalized json with a radio classification\nontology_builder = lb.OntologyBuilder(\n classifications=[ # List of Classification objects\n lb.Classification(\n class_type=lb.Classification.Type.RADIO,\n name=\"radio_question\",\n options=[\n lb.Option(value=\"first_radio_answer\"),\n lb.Option(value=\"second_radio_answer\"),\n ],\n ),\n ])\n# Creating an ontology\nontology = client.create_ontology(\"test-ontology\", ontology_builder.asdict())", + "cell_type": "code", "outputs": [], - "source": [ - "# Create normalized json with a radio classification\n", - "ontology_builder = lb.OntologyBuilder(\n", - " classifications=[ # List of Classification objects\n", - " lb.Classification(\n", - " class_type=lb.Classification.Type.RADIO,\n", - " name=\"radio_question\",\n", - " options=[\n", - " lb.Option(value=\"first_radio_answer\"),\n", - " lb.Option(value=\"second_radio_answer\"),\n", - " ],\n", - " ),\n", - " ])\n", - "# Creating an ontology\n", - "ontology = client.create_ontology(\"test-ontology\", ontology_builder.asdict())" - ] - }, - { - "cell_type": "markdown", + "execution_count": null + }, + { "metadata": {}, "source": [ "#### Attach ontology to project" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "project.setup_editor(ontology)", + "cell_type": "code", "outputs": [], - "source": [ - "project.setup_editor(ontology)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Create labels and upload them to project as ground truths" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Create labels\nlabels = []\nfor global_key in global_keys:\n labels.append(\n lb_types.Label(\n data={\"global_key\": global_key},\n annotations=[\n # Create radio classification annotation for labels\n lb_types.ClassificationAnnotation(\n name=\"radio_question\",\n value=lb_types.Radio(answer=lb_types.ClassificationAnswer(\n name=\"second_radio_answer\")),\n )\n ],\n ))\n\n# Upload labels for the data rows in project\nupload_job = lb.LabelImport.create_from_objects(\n client=client,\n project_id=project.uid,\n name=\"label_import_job\" + str(uuid.uuid4()),\n labels=labels,\n)\n\nupload_job.wait_until_done()\n\nprint(f\"Errors: {upload_job.errors}\")", + "cell_type": "code", "outputs": [], - "source": [ - "# Create labels\n", - "labels = []\n", - "for global_key in global_keys:\n", - " labels.append(\n", - " lb_types.Label(\n", - " data={\"global_key\": global_key},\n", - " annotations=[\n", - " # Create radio classification annotation for labels\n", - " lb_types.ClassificationAnnotation(\n", - " name=\"radio_question\",\n", - " value=lb_types.Radio(answer=lb_types.ClassificationAnswer(\n", - " name=\"second_radio_answer\")),\n", - " )\n", - " ],\n", - " ))\n", - "\n", - "# Upload labels for the data rows in project\n", - "upload_job = lb.LabelImport.create_from_objects(\n", - " client=client,\n", - " project_id=project.uid,\n", - " name=\"label_import_job\" + str(uuid.uuid4()),\n", - " labels=labels,\n", - ")\n", - "\n", - "upload_job.wait_until_done()\n", - "\n", - "print(f\"Errors: {upload_job.errors}\")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Move data rows in project to different task queues" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Get list of task queues for project\ntask_queues = project.task_queues()\n\nfor task_queue in task_queues:\n print(task_queue)", + "cell_type": "code", "outputs": [], - "source": [ - "# Get list of task queues for project\n", - "task_queues = project.task_queues()\n", - "\n", - "for task_queue in task_queues:\n", - " print(task_queue)" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "project.move_data_rows_to_task_queue(\n data_row_ids=lb.GlobalKeys(global_keys), # Provide a list of global keys\n task_queue_id=task_queues[2].\n uid, # Passing None moves data rows to \"Done\" task queue\n)", + "cell_type": "code", "outputs": [], - "source": [ - "project.move_data_rows_to_task_queue(\n", - " data_row_ids=lb.GlobalKeys(global_keys), # Provide a list of global keys\n", - " task_queue_id=task_queues[2].\n", - " uid, # Passing None moves data rows to \"Done\" task queue\n", - ")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Fetch project configuration" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Note the project is not fully setup many of the fields will be empty.\nprint(\"Project is not setup yet:\", project.setup_complete is None)\nprint(\"Project name:\", project.name)\nprint(\"Project description:\", project.description)\nprint(\"Media Type:\", project.media_type)\nbatches = [b for b in project.batches()]\nprint(\"Project Batches\", batches)\nprint(\"Ontology:\", project.ontology())", + "cell_type": "code", "outputs": [], - "source": [ - "# Note the project is not fully setup many of the fields will be empty.\n", - "print(\"Project is not setup yet:\", project.setup_complete is None)\n", - "print(\"Project name:\", project.name)\n", - "print(\"Project description:\", project.description)\n", - "print(\"Media Type:\", project.media_type)\n", - "batches = [b for b in project.batches()]\n", - "print(\"Project Batches\", batches)\n", - "print(\"Ontology:\", project.ontology())" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Return number of labeled data rows" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "print(\"Number of labels:\", project.get_label_count())", + "cell_type": "code", "outputs": [], - "source": [ - "print(\"Number of labels:\", project.get_label_count())" - ] + "execution_count": null }, { - "cell_type": "markdown", - "id": "818feeea", "metadata": {}, "source": [ "### Duplicate a project\n", "Please see the section [Duplicate a project](https://docs.labelbox.com/docs/create-a-project#duplicate-a-project) to have the scope of the method." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, - "id": "b01b2127", "metadata": {}, + "source": "destination_project_id = project.clone()\n\ndestination_project = client.get_project(destination_project_id)", + "cell_type": "code", "outputs": [], - "source": [ - "destination_project_id = project.clone()\n", - "\n", - "destination_project = client.get_project(destination_project_id)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Copy labels and data rows from one project to a different project\n", "In the below steps we will be copying data rows with their corresponding labels from one project to a different project with a similar ontology. First, we must set up a new project with a ontology that matches the tooling of our source project ontology." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Create an empty destination project\ndestination_project = client.create_project(\n name=\"destination-test-project\",\n description=\"a description\",\n media_type=lb.MediaType.Image,\n)\n\n# Create ontology and attach to destination project\ndestination_ontology_builder = lb.OntologyBuilder(\n classifications=[ # List of Classification objects\n lb.Classification(\n class_type=lb.Classification.Type.RADIO,\n name=\"destination_radio_question\",\n options=[\n lb.Option(value=\"destination_first_radio_answer\"),\n lb.Option(value=\"destination_second_radio_answer\"),\n ],\n ),\n ])\n\ndestination_ontology = client.create_ontology(\"dest-test-ontology\",\n ontology_builder.asdict())\n\ndestination_project.setup_editor(destination_ontology)", + "cell_type": "code", "outputs": [], - "source": [ - "# Create an empty destination project\n", - "destination_project = client.create_project(\n", - " name=\"destination-test-project\",\n", - " description=\"a description\",\n", - " media_type=lb.MediaType.Image,\n", - ")\n", - "\n", - "# Create ontology and attach to destination project\n", - "destination_ontology_builder = lb.OntologyBuilder(\n", - " classifications=[ # List of Classification objects\n", - " lb.Classification(\n", - " class_type=lb.Classification.Type.RADIO,\n", - " name=\"destination_radio_question\",\n", - " options=[\n", - " lb.Option(value=\"destination_first_radio_answer\"),\n", - " lb.Option(value=\"destination_second_radio_answer\"),\n", - " ],\n", - " ),\n", - " ])\n", - "\n", - "destination_ontology = client.create_ontology(\"dest-test-ontology\",\n", - " ontology_builder.asdict())\n", - "\n", - "destination_project.setup_editor(destination_ontology)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Copy data rows and labels\n", @@ -476,99 +321,36 @@ " * ConflictResolutionStrategy.OverrideWithAnnotations\n", "* `param batch_priority`\n", " - The priority of the batch." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Get ontology dictionary to obtain featureSchemaIds\nsource_ontology_normalized = ontology.normalized\ndestination_ontology_normalized = destination_ontology.normalized\n\nANNOTATION_ONTOLOGY_MAPPING = {\n source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0]\n [\"featureSchemaId\"], # Classification featureSchemaID\n source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0][\"options\"][0]\n [\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0][\"options\"][1]\n [\"featureSchemaId\"],\n}", + "cell_type": "code", "outputs": [], - "source": [ - "# Get ontology dictionary to obtain featureSchemaIds\n", - "source_ontology_normalized = ontology.normalized\n", - "destination_ontology_normalized = destination_ontology.normalized\n", - "\n", - "ANNOTATION_ONTOLOGY_MAPPING = {\n", - " source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:\n", - " destination_ontology_normalized[\"classifications\"][0]\n", - " [\"featureSchemaId\"], # Classification featureSchemaID\n", - " source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:\n", - " destination_ontology_normalized[\"classifications\"][0][\"options\"][0]\n", - " [\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n", - " source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:\n", - " destination_ontology_normalized[\"classifications\"][0][\"options\"][1]\n", - " [\"featureSchemaId\"],\n", - "}" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "send_to_annotate_params = {\n \"source_project_id\":\n project.uid,\n \"annotations_ontology_mapping\":\n ANNOTATION_ONTOLOGY_MAPPING,\n \"exclude_data_rows_in_project\":\n False,\n \"override_existing_annotations_rule\":\n ConflictResolutionStrategy.OverrideWithPredictions,\n \"batch_priority\":\n 5,\n}\n\n# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels.\nqueue_id = [\n queue.uid\n for queue in destination_project.task_queues()\n if queue.queue_type == \"MANUAL_REVIEW_QUEUE\"\n][0]\n\ntask = client.send_to_annotate_from_catalog(\n destination_project_id=destination_project.uid,\n task_queue_id=\n queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n batch_name=\"Prediction Import Demo Batch\",\n data_rows=lb.GlobalKeys(\n global_keys # Provide a list of global keys from source project\n ),\n params=send_to_annotate_params,\n)\n\ntask.wait_till_done()\n\nprint(f\"Errors: {task.errors}\")", + "cell_type": "code", "outputs": [], - "source": [ - "send_to_annotate_params = {\n", - " \"source_project_id\":\n", - " project.uid,\n", - " \"annotations_ontology_mapping\":\n", - " ANNOTATION_ONTOLOGY_MAPPING,\n", - " \"exclude_data_rows_in_project\":\n", - " False,\n", - " \"override_existing_annotations_rule\":\n", - " ConflictResolutionStrategy.OverrideWithPredictions,\n", - " \"batch_priority\":\n", - " 5,\n", - "}\n", - "\n", - "# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels.\n", - "queue_id = [\n", - " queue.uid\n", - " for queue in destination_project.task_queues()\n", - " if queue.queue_type == \"MANUAL_REVIEW_QUEUE\"\n", - "][0]\n", - "\n", - "task = client.send_to_annotate_from_catalog(\n", - " destination_project_id=destination_project.uid,\n", - " task_queue_id=\n", - " queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n", - " batch_name=\"Prediction Import Demo Batch\",\n", - " data_rows=lb.GlobalKeys(\n", - " global_keys # Provide a list of global keys from source project\n", - " ),\n", - " params=send_to_annotate_params,\n", - ")\n", - "\n", - "task.wait_till_done()\n", - "\n", - "print(f\"Errors: {task.errors}\")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Clean Up" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# project.delete()\n# destination_project.delete()\n# dataset.delete()\n# client.delete_unused_ontology(destination_ontology.uid)\n# client.delete_unused_ontology(ontology.uid)", + "cell_type": "code", "outputs": [], - "source": [ - "# project.delete()\n", - "# destination_project.delete()\n", - "# dataset.delete()\n", - "# client.delete_unused_ontology(destination_ontology.uid)\n", - "# client.delete_unused_ontology(ontology.uid)" - ] + "execution_count": null } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} + ] +} \ No newline at end of file From 957cb53102884ad586da62c7d73b8df1aaa083e2 Mon Sep 17 00:00:00 2001 From: paulnoirel <87332996+paulnoirel@users.noreply.github.com> Date: Wed, 29 May 2024 17:50:20 +0100 Subject: [PATCH 3/4] Fix typo in example --- examples/basics/projects.ipynb | 450 ++++++++++++++++++++++++--------- 1 file changed, 332 insertions(+), 118 deletions(-) diff --git a/examples/basics/projects.ipynb b/examples/basics/projects.ipynb index df78ea04a..d860fc14f 100644 --- a/examples/basics/projects.ipynb +++ b/examples/basics/projects.ipynb @@ -1,18 +1,16 @@ { - "nbformat": 4, - "nbformat_minor": 5, - "metadata": {}, "cells": [ { + "cell_type": "markdown", "metadata": {}, "source": [ - "", - " ", + "\n", + " \n", "\n" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "\n", @@ -24,17 +22,17 @@ "\n", "" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "# Projects" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "* A project can be thought of as a specific labeling task on a set of labels\n", @@ -42,261 +40,414 @@ "* Each project has an ontology which defines the types of annotations supported during the labeling process\n", "**Note that there is a lot of advanced usage that is not covered in this notebook. See examples/project_configuration/project_setup.ipynb for those functions**\n", "* Also note that deprecated functions are not explained here." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "%pip install -q \"labelbox[data]\"", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "%pip install -q \"labelbox[data]\"" + ] }, { - "metadata": {}, - "source": "import labelbox as lb\nimport labelbox.types as lb_types\nfrom labelbox.schema.conflict_resolution_strategy import (\n ConflictResolutionStrategy,)\nimport uuid", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "import labelbox as lb\n", + "import labelbox.types as lb_types\n", + "from labelbox.schema.conflict_resolution_strategy import (\n", + " ConflictResolutionStrategy,)\n", + "import uuid" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "# API Key and Client\n", "Provide a valid api key below in order to properly connect to the Labelbox Client." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Add your API key\nAPI_KEY = \"\"\n# To get your API key go to: Workspace settings -> API -> Create API Key\nclient = lb.Client(api_key=API_KEY)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Add your API key\n", + "API_KEY = \"\"\n", + "# To get your API key go to: Workspace settings -> API -> Create API Key\n", + "client = lb.Client(api_key=API_KEY)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Create a project\n" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Creates an empty project\nproject = client.create_project(\n name=\"my-test-project\",\n description=\"a description\",\n media_type=lb.MediaType.Image,\n)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Creates an empty project\n", + "project = client.create_project(\n", + " name=\"my-test-project\",\n", + " description=\"a description\",\n", + " media_type=lb.MediaType.Image,\n", + ")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Create a dataset with data rows" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "dataset = client.create_dataset(name=\"project-demo-dataset\")\nglobal_keys = []\nuploads = []\n# Generate data rows\nfor i in range(1, 9):\n gb_key = \"TEST-ID-%id\" % uuid.uuid1()\n uploads.append({\n \"row_data\":\n f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n \"global_key\":\n gb_key,\n })\n global_keys.append(gb_key)\n\ntask = dataset.create_data_rows(uploads)\ntask.wait_till_done()\nprint(\"ERRORS: \", task.errors)\nprint(\"RESULT URL: \", task.result_url)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "dataset = client.create_dataset(name=\"project-demo-dataset\")\n", + "global_keys = []\n", + "uploads = []\n", + "# Generate data rows\n", + "for i in range(1, 9):\n", + " gb_key = \"TEST-ID-%id\" % uuid.uuid1()\n", + " uploads.append({\n", + " \"row_data\":\n", + " f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n", + " \"global_key\":\n", + " gb_key,\n", + " })\n", + " global_keys.append(gb_key)\n", + "\n", + "task = dataset.create_data_rows(uploads)\n", + "task.wait_till_done()\n", + "print(\"ERRORS: \", task.errors)\n", + "print(\"RESULT URL: \", task.result_url)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Add data rows to a project \n" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "project.create_batch(\n \"project-demo\", # each batch in a project must have a unique name\n global_keys=\n global_keys, # paginated collection of data row objects, list of data row ids or global keys\n priority=1, # priority between 1(highest) - 5(lowest)\n)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "project.create_batch(\n", + " \"project-demo\", # each batch in a project must have a unique name\n", + " global_keys=\n", + " global_keys, # paginated collection of data row objects, list of data row ids or global keys\n", + " priority=1, # priority between 1(highest) - 5(lowest)\n", + ")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Create tags and assign them to a project\n", "In this section, we are creating a tag in the ontology and associating it with a project. Then we are listing the tags attached to a project.\n" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Create a tag" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Get the organization\norganization = client.get_organization()\n\ntag = organization.create_resource_tag({\n \"text\": \"new-tag-name\",\n \"color\": \"4ed2f9\"\n})", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Get the organization\n", + "organization = client.get_organization()\n", + "\n", + "tag = organization.create_resource_tag({\n", + " \"text\": \"new-tag-name\",\n", + " \"color\": \"4ed2f9\"\n", + "})" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Assign the tag to a project" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "tags = project.update_project_resource_tags([tag.uid])", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "tags = project.update_project_resource_tags([tag.uid])" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Get project tags" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "tags = project.get_resource_tags()", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "tags = project.get_resource_tags()" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Attach ontology and label data rows\n", "\n", "In this section, we are creating an ontology to attach to a project and creating labels to import as ground truths. We need this setup to demonstrate other methods later in the demo. For more information, please reference our [Ontology](https://docs.labelbox.com/reference/ontology) and [Import Image Annotation](https://docs.labelbox.com/reference/import-image-annotations) development guides." - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Create your ontology" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Create normalized json with a radio classification\nontology_builder = lb.OntologyBuilder(\n classifications=[ # List of Classification objects\n lb.Classification(\n class_type=lb.Classification.Type.RADIO,\n name=\"radio_question\",\n options=[\n lb.Option(value=\"first_radio_answer\"),\n lb.Option(value=\"second_radio_answer\"),\n ],\n ),\n ])\n# Creating an ontology\nontology = client.create_ontology(\"test-ontology\", ontology_builder.asdict())", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null - }, - { + "source": [ + "# Create normalized json with a radio classification\n", + "ontology_builder = lb.OntologyBuilder(\n", + " classifications=[ # List of Classification objects\n", + " lb.Classification(\n", + " class_type=lb.Classification.Type.RADIO,\n", + " name=\"radio_question\",\n", + " options=[\n", + " lb.Option(value=\"first_radio_answer\"),\n", + " lb.Option(value=\"second_radio_answer\"),\n", + " ],\n", + " ),\n", + " ])\n", + "# Creating an ontology\n", + "ontology = client.create_ontology(\"test-ontology\", ontology_builder.asdict())" + ] + }, + { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Attach ontology to project" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "project.setup_editor(ontology)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "project.setup_editor(ontology)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Create labels and upload them to project as ground truths" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Create labels\nlabels = []\nfor global_key in global_keys:\n labels.append(\n lb_types.Label(\n data={\"global_key\": global_key},\n annotations=[\n # Create radio classification annotation for labels\n lb_types.ClassificationAnnotation(\n name=\"radio_question\",\n value=lb_types.Radio(answer=lb_types.ClassificationAnswer(\n name=\"second_radio_answer\")),\n )\n ],\n ))\n\n# Upload labels for the data rows in project\nupload_job = lb.LabelImport.create_from_objects(\n client=client,\n project_id=project.uid,\n name=\"label_import_job\" + str(uuid.uuid4()),\n labels=labels,\n)\n\nupload_job.wait_until_done()\n\nprint(f\"Errors: {upload_job.errors}\")", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Create labels\n", + "labels = []\n", + "for global_key in global_keys:\n", + " labels.append(\n", + " lb_types.Label(\n", + " data={\"global_key\": global_key},\n", + " annotations=[\n", + " # Create radio classification annotation for labels\n", + " lb_types.ClassificationAnnotation(\n", + " name=\"radio_question\",\n", + " value=lb_types.Radio(answer=lb_types.ClassificationAnswer(\n", + " name=\"second_radio_answer\")),\n", + " )\n", + " ],\n", + " ))\n", + "\n", + "# Upload labels for the data rows in project\n", + "upload_job = lb.LabelImport.create_from_objects(\n", + " client=client,\n", + " project_id=project.uid,\n", + " name=\"label_import_job\" + str(uuid.uuid4()),\n", + " labels=labels,\n", + ")\n", + "\n", + "upload_job.wait_until_done()\n", + "\n", + "print(f\"Errors: {upload_job.errors}\")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Move data rows in project to different task queues" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Get list of task queues for project\ntask_queues = project.task_queues()\n\nfor task_queue in task_queues:\n print(task_queue)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Get list of task queues for project\n", + "task_queues = project.task_queues()\n", + "\n", + "for task_queue in task_queues:\n", + " print(task_queue)" + ] }, { - "metadata": {}, - "source": "project.move_data_rows_to_task_queue(\n data_row_ids=lb.GlobalKeys(global_keys), # Provide a list of global keys\n task_queue_id=task_queues[2].\n uid, # Passing None moves data rows to \"Done\" task queue\n)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "project.move_data_rows_to_task_queue(\n", + " data_row_ids=lb.GlobalKeys(global_keys), # Provide a list of global keys\n", + " task_queue_id=task_queues[2].\n", + " uid, # Passing None moves data rows to \"Done\" task queue\n", + ")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Fetch project configuration" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Note the project is not fully setup many of the fields will be empty.\nprint(\"Project is not setup yet:\", project.setup_complete is None)\nprint(\"Project name:\", project.name)\nprint(\"Project description:\", project.description)\nprint(\"Media Type:\", project.media_type)\nbatches = [b for b in project.batches()]\nprint(\"Project Batches\", batches)\nprint(\"Ontology:\", project.ontology())", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Note the project is not fully setup many of the fields will be empty.\n", + "print(\"Project is not setup yet:\", project.setup_complete is None)\n", + "print(\"Project name:\", project.name)\n", + "print(\"Project description:\", project.description)\n", + "print(\"Media Type:\", project.media_type)\n", + "batches = [b for b in project.batches()]\n", + "print(\"Project Batches\", batches)\n", + "print(\"Ontology:\", project.ontology())" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Return number of labeled data rows" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "print(\"Number of labels:\", project.get_label_count())", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "print(\"Number of labels:\", project.get_label_count())" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Duplicate a project\n", "Please see the section [Duplicate a project](https://docs.labelbox.com/docs/create-a-project#duplicate-a-project) to have the scope of the method." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "destination_project_id = project.clone()\n\ndestination_project = client.get_project(destination_project_id)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "destination_project = project.clone()" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Copy labels and data rows from one project to a different project\n", "In the below steps we will be copying data rows with their corresponding labels from one project to a different project with a similar ontology. First, we must set up a new project with a ontology that matches the tooling of our source project ontology." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Create an empty destination project\ndestination_project = client.create_project(\n name=\"destination-test-project\",\n description=\"a description\",\n media_type=lb.MediaType.Image,\n)\n\n# Create ontology and attach to destination project\ndestination_ontology_builder = lb.OntologyBuilder(\n classifications=[ # List of Classification objects\n lb.Classification(\n class_type=lb.Classification.Type.RADIO,\n name=\"destination_radio_question\",\n options=[\n lb.Option(value=\"destination_first_radio_answer\"),\n lb.Option(value=\"destination_second_radio_answer\"),\n ],\n ),\n ])\n\ndestination_ontology = client.create_ontology(\"dest-test-ontology\",\n ontology_builder.asdict())\n\ndestination_project.setup_editor(destination_ontology)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Create an empty destination project\n", + "destination_project = client.create_project(\n", + " name=\"destination-test-project\",\n", + " description=\"a description\",\n", + " media_type=lb.MediaType.Image,\n", + ")\n", + "\n", + "# Create ontology and attach to destination project\n", + "destination_ontology_builder = lb.OntologyBuilder(\n", + " classifications=[ # List of Classification objects\n", + " lb.Classification(\n", + " class_type=lb.Classification.Type.RADIO,\n", + " name=\"destination_radio_question\",\n", + " options=[\n", + " lb.Option(value=\"destination_first_radio_answer\"),\n", + " lb.Option(value=\"destination_second_radio_answer\"),\n", + " ],\n", + " ),\n", + " ])\n", + "\n", + "destination_ontology = client.create_ontology(\"dest-test-ontology\",\n", + " ontology_builder.asdict())\n", + "\n", + "destination_project.setup_editor(destination_ontology)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "#### Copy data rows and labels\n", @@ -321,36 +472,99 @@ " * ConflictResolutionStrategy.OverrideWithAnnotations\n", "* `param batch_priority`\n", " - The priority of the batch." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Get ontology dictionary to obtain featureSchemaIds\nsource_ontology_normalized = ontology.normalized\ndestination_ontology_normalized = destination_ontology.normalized\n\nANNOTATION_ONTOLOGY_MAPPING = {\n source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0]\n [\"featureSchemaId\"], # Classification featureSchemaID\n source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0][\"options\"][0]\n [\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0][\"options\"][1]\n [\"featureSchemaId\"],\n}", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Get ontology dictionary to obtain featureSchemaIds\n", + "source_ontology_normalized = ontology.normalized\n", + "destination_ontology_normalized = destination_ontology.normalized\n", + "\n", + "ANNOTATION_ONTOLOGY_MAPPING = {\n", + " source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:\n", + " destination_ontology_normalized[\"classifications\"][0]\n", + " [\"featureSchemaId\"], # Classification featureSchemaID\n", + " source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:\n", + " destination_ontology_normalized[\"classifications\"][0][\"options\"][0]\n", + " [\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n", + " source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:\n", + " destination_ontology_normalized[\"classifications\"][0][\"options\"][1]\n", + " [\"featureSchemaId\"],\n", + "}" + ] }, { - "metadata": {}, - "source": "send_to_annotate_params = {\n \"source_project_id\":\n project.uid,\n \"annotations_ontology_mapping\":\n ANNOTATION_ONTOLOGY_MAPPING,\n \"exclude_data_rows_in_project\":\n False,\n \"override_existing_annotations_rule\":\n ConflictResolutionStrategy.OverrideWithPredictions,\n \"batch_priority\":\n 5,\n}\n\n# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels.\nqueue_id = [\n queue.uid\n for queue in destination_project.task_queues()\n if queue.queue_type == \"MANUAL_REVIEW_QUEUE\"\n][0]\n\ntask = client.send_to_annotate_from_catalog(\n destination_project_id=destination_project.uid,\n task_queue_id=\n queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n batch_name=\"Prediction Import Demo Batch\",\n data_rows=lb.GlobalKeys(\n global_keys # Provide a list of global keys from source project\n ),\n params=send_to_annotate_params,\n)\n\ntask.wait_till_done()\n\nprint(f\"Errors: {task.errors}\")", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "send_to_annotate_params = {\n", + " \"source_project_id\":\n", + " project.uid,\n", + " \"annotations_ontology_mapping\":\n", + " ANNOTATION_ONTOLOGY_MAPPING,\n", + " \"exclude_data_rows_in_project\":\n", + " False,\n", + " \"override_existing_annotations_rule\":\n", + " ConflictResolutionStrategy.OverrideWithPredictions,\n", + " \"batch_priority\":\n", + " 5,\n", + "}\n", + "\n", + "# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels.\n", + "queue_id = [\n", + " queue.uid\n", + " for queue in destination_project.task_queues()\n", + " if queue.queue_type == \"MANUAL_REVIEW_QUEUE\"\n", + "][0]\n", + "\n", + "task = client.send_to_annotate_from_catalog(\n", + " destination_project_id=destination_project.uid,\n", + " task_queue_id=\n", + " queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n", + " batch_name=\"Prediction Import Demo Batch\",\n", + " data_rows=lb.GlobalKeys(\n", + " global_keys # Provide a list of global keys from source project\n", + " ),\n", + " params=send_to_annotate_params,\n", + ")\n", + "\n", + "task.wait_till_done()\n", + "\n", + "print(f\"Errors: {task.errors}\")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Clean Up" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# project.delete()\n# destination_project.delete()\n# dataset.delete()\n# client.delete_unused_ontology(destination_ontology.uid)\n# client.delete_unused_ontology(ontology.uid)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# project.delete()\n", + "# destination_project.delete()\n", + "# dataset.delete()\n", + "# client.delete_unused_ontology(destination_ontology.uid)\n", + "# client.delete_unused_ontology(ontology.uid)" + ] } - ] -} \ No newline at end of file + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 88f970c6dfc3bb7b77fa10571b623e6d15624871 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 29 May 2024 16:51:34 +0000 Subject: [PATCH 4/4] :art: Cleaned --- examples/basics/projects.ipynb | 450 +++++++++------------------------ 1 file changed, 118 insertions(+), 332 deletions(-) diff --git a/examples/basics/projects.ipynb b/examples/basics/projects.ipynb index d860fc14f..0da2c769d 100644 --- a/examples/basics/projects.ipynb +++ b/examples/basics/projects.ipynb @@ -1,16 +1,18 @@ { + "nbformat": 4, + "nbformat_minor": 5, + "metadata": {}, "cells": [ { - "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - " \n", + "", + " ", "\n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "\n", @@ -22,17 +24,17 @@ "\n", "" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "# Projects" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "* A project can be thought of as a specific labeling task on a set of labels\n", @@ -40,414 +42,261 @@ "* Each project has an ontology which defines the types of annotations supported during the labeling process\n", "**Note that there is a lot of advanced usage that is not covered in this notebook. See examples/project_configuration/project_setup.ipynb for those functions**\n", "* Also note that deprecated functions are not explained here." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "%pip install -q \"labelbox[data]\"", + "cell_type": "code", "outputs": [], - "source": [ - "%pip install -q \"labelbox[data]\"" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "import labelbox as lb\nimport labelbox.types as lb_types\nfrom labelbox.schema.conflict_resolution_strategy import (\n ConflictResolutionStrategy,)\nimport uuid", + "cell_type": "code", "outputs": [], - "source": [ - "import labelbox as lb\n", - "import labelbox.types as lb_types\n", - "from labelbox.schema.conflict_resolution_strategy import (\n", - " ConflictResolutionStrategy,)\n", - "import uuid" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "# API Key and Client\n", "Provide a valid api key below in order to properly connect to the Labelbox Client." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Add your API key\nAPI_KEY = \"\"\n# To get your API key go to: Workspace settings -> API -> Create API Key\nclient = lb.Client(api_key=API_KEY)", + "cell_type": "code", "outputs": [], - "source": [ - "# Add your API key\n", - "API_KEY = \"\"\n", - "# To get your API key go to: Workspace settings -> API -> Create API Key\n", - "client = lb.Client(api_key=API_KEY)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Create a project\n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Creates an empty project\nproject = client.create_project(\n name=\"my-test-project\",\n description=\"a description\",\n media_type=lb.MediaType.Image,\n)", + "cell_type": "code", "outputs": [], - "source": [ - "# Creates an empty project\n", - "project = client.create_project(\n", - " name=\"my-test-project\",\n", - " description=\"a description\",\n", - " media_type=lb.MediaType.Image,\n", - ")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Create a dataset with data rows" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "dataset = client.create_dataset(name=\"project-demo-dataset\")\nglobal_keys = []\nuploads = []\n# Generate data rows\nfor i in range(1, 9):\n gb_key = \"TEST-ID-%id\" % uuid.uuid1()\n uploads.append({\n \"row_data\":\n f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n \"global_key\":\n gb_key,\n })\n global_keys.append(gb_key)\n\ntask = dataset.create_data_rows(uploads)\ntask.wait_till_done()\nprint(\"ERRORS: \", task.errors)\nprint(\"RESULT URL: \", task.result_url)", + "cell_type": "code", "outputs": [], - "source": [ - "dataset = client.create_dataset(name=\"project-demo-dataset\")\n", - "global_keys = []\n", - "uploads = []\n", - "# Generate data rows\n", - "for i in range(1, 9):\n", - " gb_key = \"TEST-ID-%id\" % uuid.uuid1()\n", - " uploads.append({\n", - " \"row_data\":\n", - " f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n", - " \"global_key\":\n", - " gb_key,\n", - " })\n", - " global_keys.append(gb_key)\n", - "\n", - "task = dataset.create_data_rows(uploads)\n", - "task.wait_till_done()\n", - "print(\"ERRORS: \", task.errors)\n", - "print(\"RESULT URL: \", task.result_url)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Add data rows to a project \n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "project.create_batch(\n \"project-demo\", # each batch in a project must have a unique name\n global_keys=\n global_keys, # paginated collection of data row objects, list of data row ids or global keys\n priority=1, # priority between 1(highest) - 5(lowest)\n)", + "cell_type": "code", "outputs": [], - "source": [ - "project.create_batch(\n", - " \"project-demo\", # each batch in a project must have a unique name\n", - " global_keys=\n", - " global_keys, # paginated collection of data row objects, list of data row ids or global keys\n", - " priority=1, # priority between 1(highest) - 5(lowest)\n", - ")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Create tags and assign them to a project\n", "In this section, we are creating a tag in the ontology and associating it with a project. Then we are listing the tags attached to a project.\n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Create a tag" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Get the organization\norganization = client.get_organization()\n\ntag = organization.create_resource_tag({\n \"text\": \"new-tag-name\",\n \"color\": \"4ed2f9\"\n})", + "cell_type": "code", "outputs": [], - "source": [ - "# Get the organization\n", - "organization = client.get_organization()\n", - "\n", - "tag = organization.create_resource_tag({\n", - " \"text\": \"new-tag-name\",\n", - " \"color\": \"4ed2f9\"\n", - "})" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Assign the tag to a project" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "tags = project.update_project_resource_tags([tag.uid])", + "cell_type": "code", "outputs": [], - "source": [ - "tags = project.update_project_resource_tags([tag.uid])" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Get project tags" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "tags = project.get_resource_tags()", + "cell_type": "code", "outputs": [], - "source": [ - "tags = project.get_resource_tags()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Attach ontology and label data rows\n", "\n", "In this section, we are creating an ontology to attach to a project and creating labels to import as ground truths. We need this setup to demonstrate other methods later in the demo. For more information, please reference our [Ontology](https://docs.labelbox.com/reference/ontology) and [Import Image Annotation](https://docs.labelbox.com/reference/import-image-annotations) development guides." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Create your ontology" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Create normalized json with a radio classification\nontology_builder = lb.OntologyBuilder(\n classifications=[ # List of Classification objects\n lb.Classification(\n class_type=lb.Classification.Type.RADIO,\n name=\"radio_question\",\n options=[\n lb.Option(value=\"first_radio_answer\"),\n lb.Option(value=\"second_radio_answer\"),\n ],\n ),\n ])\n# Creating an ontology\nontology = client.create_ontology(\"test-ontology\", ontology_builder.asdict())", + "cell_type": "code", "outputs": [], - "source": [ - "# Create normalized json with a radio classification\n", - "ontology_builder = lb.OntologyBuilder(\n", - " classifications=[ # List of Classification objects\n", - " lb.Classification(\n", - " class_type=lb.Classification.Type.RADIO,\n", - " name=\"radio_question\",\n", - " options=[\n", - " lb.Option(value=\"first_radio_answer\"),\n", - " lb.Option(value=\"second_radio_answer\"),\n", - " ],\n", - " ),\n", - " ])\n", - "# Creating an ontology\n", - "ontology = client.create_ontology(\"test-ontology\", ontology_builder.asdict())" - ] - }, - { - "cell_type": "markdown", + "execution_count": null + }, + { "metadata": {}, "source": [ "#### Attach ontology to project" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "project.setup_editor(ontology)", + "cell_type": "code", "outputs": [], - "source": [ - "project.setup_editor(ontology)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Create labels and upload them to project as ground truths" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Create labels\nlabels = []\nfor global_key in global_keys:\n labels.append(\n lb_types.Label(\n data={\"global_key\": global_key},\n annotations=[\n # Create radio classification annotation for labels\n lb_types.ClassificationAnnotation(\n name=\"radio_question\",\n value=lb_types.Radio(answer=lb_types.ClassificationAnswer(\n name=\"second_radio_answer\")),\n )\n ],\n ))\n\n# Upload labels for the data rows in project\nupload_job = lb.LabelImport.create_from_objects(\n client=client,\n project_id=project.uid,\n name=\"label_import_job\" + str(uuid.uuid4()),\n labels=labels,\n)\n\nupload_job.wait_until_done()\n\nprint(f\"Errors: {upload_job.errors}\")", + "cell_type": "code", "outputs": [], - "source": [ - "# Create labels\n", - "labels = []\n", - "for global_key in global_keys:\n", - " labels.append(\n", - " lb_types.Label(\n", - " data={\"global_key\": global_key},\n", - " annotations=[\n", - " # Create radio classification annotation for labels\n", - " lb_types.ClassificationAnnotation(\n", - " name=\"radio_question\",\n", - " value=lb_types.Radio(answer=lb_types.ClassificationAnswer(\n", - " name=\"second_radio_answer\")),\n", - " )\n", - " ],\n", - " ))\n", - "\n", - "# Upload labels for the data rows in project\n", - "upload_job = lb.LabelImport.create_from_objects(\n", - " client=client,\n", - " project_id=project.uid,\n", - " name=\"label_import_job\" + str(uuid.uuid4()),\n", - " labels=labels,\n", - ")\n", - "\n", - "upload_job.wait_until_done()\n", - "\n", - "print(f\"Errors: {upload_job.errors}\")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Move data rows in project to different task queues" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Get list of task queues for project\ntask_queues = project.task_queues()\n\nfor task_queue in task_queues:\n print(task_queue)", + "cell_type": "code", "outputs": [], - "source": [ - "# Get list of task queues for project\n", - "task_queues = project.task_queues()\n", - "\n", - "for task_queue in task_queues:\n", - " print(task_queue)" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "project.move_data_rows_to_task_queue(\n data_row_ids=lb.GlobalKeys(global_keys), # Provide a list of global keys\n task_queue_id=task_queues[2].\n uid, # Passing None moves data rows to \"Done\" task queue\n)", + "cell_type": "code", "outputs": [], - "source": [ - "project.move_data_rows_to_task_queue(\n", - " data_row_ids=lb.GlobalKeys(global_keys), # Provide a list of global keys\n", - " task_queue_id=task_queues[2].\n", - " uid, # Passing None moves data rows to \"Done\" task queue\n", - ")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Fetch project configuration" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Note the project is not fully setup many of the fields will be empty.\nprint(\"Project is not setup yet:\", project.setup_complete is None)\nprint(\"Project name:\", project.name)\nprint(\"Project description:\", project.description)\nprint(\"Media Type:\", project.media_type)\nbatches = [b for b in project.batches()]\nprint(\"Project Batches\", batches)\nprint(\"Ontology:\", project.ontology())", + "cell_type": "code", "outputs": [], - "source": [ - "# Note the project is not fully setup many of the fields will be empty.\n", - "print(\"Project is not setup yet:\", project.setup_complete is None)\n", - "print(\"Project name:\", project.name)\n", - "print(\"Project description:\", project.description)\n", - "print(\"Media Type:\", project.media_type)\n", - "batches = [b for b in project.batches()]\n", - "print(\"Project Batches\", batches)\n", - "print(\"Ontology:\", project.ontology())" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Return number of labeled data rows" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "print(\"Number of labels:\", project.get_label_count())", + "cell_type": "code", "outputs": [], - "source": [ - "print(\"Number of labels:\", project.get_label_count())" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Duplicate a project\n", "Please see the section [Duplicate a project](https://docs.labelbox.com/docs/create-a-project#duplicate-a-project) to have the scope of the method." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "destination_project = project.clone()", + "cell_type": "code", "outputs": [], - "source": [ - "destination_project = project.clone()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Copy labels and data rows from one project to a different project\n", "In the below steps we will be copying data rows with their corresponding labels from one project to a different project with a similar ontology. First, we must set up a new project with a ontology that matches the tooling of our source project ontology." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Create an empty destination project\ndestination_project = client.create_project(\n name=\"destination-test-project\",\n description=\"a description\",\n media_type=lb.MediaType.Image,\n)\n\n# Create ontology and attach to destination project\ndestination_ontology_builder = lb.OntologyBuilder(\n classifications=[ # List of Classification objects\n lb.Classification(\n class_type=lb.Classification.Type.RADIO,\n name=\"destination_radio_question\",\n options=[\n lb.Option(value=\"destination_first_radio_answer\"),\n lb.Option(value=\"destination_second_radio_answer\"),\n ],\n ),\n ])\n\ndestination_ontology = client.create_ontology(\"dest-test-ontology\",\n ontology_builder.asdict())\n\ndestination_project.setup_editor(destination_ontology)", + "cell_type": "code", "outputs": [], - "source": [ - "# Create an empty destination project\n", - "destination_project = client.create_project(\n", - " name=\"destination-test-project\",\n", - " description=\"a description\",\n", - " media_type=lb.MediaType.Image,\n", - ")\n", - "\n", - "# Create ontology and attach to destination project\n", - "destination_ontology_builder = lb.OntologyBuilder(\n", - " classifications=[ # List of Classification objects\n", - " lb.Classification(\n", - " class_type=lb.Classification.Type.RADIO,\n", - " name=\"destination_radio_question\",\n", - " options=[\n", - " lb.Option(value=\"destination_first_radio_answer\"),\n", - " lb.Option(value=\"destination_second_radio_answer\"),\n", - " ],\n", - " ),\n", - " ])\n", - "\n", - "destination_ontology = client.create_ontology(\"dest-test-ontology\",\n", - " ontology_builder.asdict())\n", - "\n", - "destination_project.setup_editor(destination_ontology)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "#### Copy data rows and labels\n", @@ -472,99 +321,36 @@ " * ConflictResolutionStrategy.OverrideWithAnnotations\n", "* `param batch_priority`\n", " - The priority of the batch." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Get ontology dictionary to obtain featureSchemaIds\nsource_ontology_normalized = ontology.normalized\ndestination_ontology_normalized = destination_ontology.normalized\n\nANNOTATION_ONTOLOGY_MAPPING = {\n source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0]\n [\"featureSchemaId\"], # Classification featureSchemaID\n source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0][\"options\"][0]\n [\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:\n destination_ontology_normalized[\"classifications\"][0][\"options\"][1]\n [\"featureSchemaId\"],\n}", + "cell_type": "code", "outputs": [], - "source": [ - "# Get ontology dictionary to obtain featureSchemaIds\n", - "source_ontology_normalized = ontology.normalized\n", - "destination_ontology_normalized = destination_ontology.normalized\n", - "\n", - "ANNOTATION_ONTOLOGY_MAPPING = {\n", - " source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:\n", - " destination_ontology_normalized[\"classifications\"][0]\n", - " [\"featureSchemaId\"], # Classification featureSchemaID\n", - " source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:\n", - " destination_ontology_normalized[\"classifications\"][0][\"options\"][0]\n", - " [\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n", - " source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:\n", - " destination_ontology_normalized[\"classifications\"][0][\"options\"][1]\n", - " [\"featureSchemaId\"],\n", - "}" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "send_to_annotate_params = {\n \"source_project_id\":\n project.uid,\n \"annotations_ontology_mapping\":\n ANNOTATION_ONTOLOGY_MAPPING,\n \"exclude_data_rows_in_project\":\n False,\n \"override_existing_annotations_rule\":\n ConflictResolutionStrategy.OverrideWithPredictions,\n \"batch_priority\":\n 5,\n}\n\n# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels.\nqueue_id = [\n queue.uid\n for queue in destination_project.task_queues()\n if queue.queue_type == \"MANUAL_REVIEW_QUEUE\"\n][0]\n\ntask = client.send_to_annotate_from_catalog(\n destination_project_id=destination_project.uid,\n task_queue_id=\n queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n batch_name=\"Prediction Import Demo Batch\",\n data_rows=lb.GlobalKeys(\n global_keys # Provide a list of global keys from source project\n ),\n params=send_to_annotate_params,\n)\n\ntask.wait_till_done()\n\nprint(f\"Errors: {task.errors}\")", + "cell_type": "code", "outputs": [], - "source": [ - "send_to_annotate_params = {\n", - " \"source_project_id\":\n", - " project.uid,\n", - " \"annotations_ontology_mapping\":\n", - " ANNOTATION_ONTOLOGY_MAPPING,\n", - " \"exclude_data_rows_in_project\":\n", - " False,\n", - " \"override_existing_annotations_rule\":\n", - " ConflictResolutionStrategy.OverrideWithPredictions,\n", - " \"batch_priority\":\n", - " 5,\n", - "}\n", - "\n", - "# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels.\n", - "queue_id = [\n", - " queue.uid\n", - " for queue in destination_project.task_queues()\n", - " if queue.queue_type == \"MANUAL_REVIEW_QUEUE\"\n", - "][0]\n", - "\n", - "task = client.send_to_annotate_from_catalog(\n", - " destination_project_id=destination_project.uid,\n", - " task_queue_id=\n", - " queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n", - " batch_name=\"Prediction Import Demo Batch\",\n", - " data_rows=lb.GlobalKeys(\n", - " global_keys # Provide a list of global keys from source project\n", - " ),\n", - " params=send_to_annotate_params,\n", - ")\n", - "\n", - "task.wait_till_done()\n", - "\n", - "print(f\"Errors: {task.errors}\")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Clean Up" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# project.delete()\n# destination_project.delete()\n# dataset.delete()\n# client.delete_unused_ontology(destination_ontology.uid)\n# client.delete_unused_ontology(ontology.uid)", + "cell_type": "code", "outputs": [], - "source": [ - "# project.delete()\n", - "# destination_project.delete()\n", - "# dataset.delete()\n", - "# client.delete_unused_ontology(destination_ontology.uid)\n", - "# client.delete_unused_ontology(ontology.uid)" - ] + "execution_count": null } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} + ] +} \ No newline at end of file