Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 49 additions & 42 deletions examples/basics/projects.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<td>\n",
" <a target=\"_blank\" href=\"https://labelbox.com\" ><img src=\"https://labelbox.com/blog/content/images/2021/02/logo-v4.svg\" width=256/></a>\n",
"</td>"
],
"metadata": {}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<td>\n",
"<a href=\"https://colab.research.google.com/github/Labelbox/labelbox-python/blob/develop/examples/basics/projects.ipynb\" target=\"_blank\"><img\n",
Expand All @@ -21,18 +22,18 @@
"<a href=\"https://github.com/Labelbox/labelbox-python/tree/develop/examples/basics/projects.ipynb\" target=\"_blank\"><img\n",
"src=\"https://img.shields.io/badge/GitHub-100000?logo=github&logoColor=white\" alt=\"GitHub\"></a>\n",
"</td>"
],
"metadata": {}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Projects"
],
"metadata": {}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* A project can be thought of as a specific labeling task on a set of labels\n",
"* That set of labels is defined by the datasets attached to the project\n",
Expand All @@ -41,123 +42,129 @@
"\n",
"** Note that there is a lot of advanced usage that is not covered in this notebook. See project_setup for those functions.\n",
"* Also note that deprecated functions are not explained here."
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"!pip install labelbox"
],
"outputs": [],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from labelbox import Client\n",
"from labelbox.schema.media_type import MediaType\n",
"import os"
],
"outputs": [],
"metadata": {}
]
},
{
"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."
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# Add your api key\n",
"API_KEY = None\n",
"client = Client(api_key=API_KEY)"
],
"outputs": [],
"metadata": {}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create\n"
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# Creates an empty project\n",
"# Creates an empty project without a media type\n",
"project = client.create_project(name=\"my-test-project\",\n",
" description=\"a description\")"
],
"outputs": [],
"metadata": {}
" description=\"a description\")\n",
"\n",
"# Creates an empty project a media type\n",
"project = client.create_project(name=\"my-test-project\",\n",
" description=\"a description\",\n",
" media_type=MediaType.Image)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Read"
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Note the project is not setup (so a lot of these fiels are empty). Follow the project setup workflow\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",
"print(\"Dataset:\", list(project.datasets()))\n",
"print(\"Ontology:\", project.ontology().normalized)\n",
"print(\"Benchmarks:\", project.benchmarks())"
],
"outputs": [],
"metadata": {}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Update\n",
"\n"
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Attach dataset\n",
"ds = client.create_dataset(name=\"test-ds\")\n",
"project.datasets.connect(ds)\n",
"print([ds.name for ds in project.datasets()])\n",
"ds.delete()"
],
"outputs": [],
"metadata": {}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Delete"
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"project.delete()"
],
"outputs": [],
"metadata": {}
]
}
],
"metadata": {
Expand All @@ -181,4 +188,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
1 change: 1 addition & 0 deletions labelbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@
from labelbox.schema.iam_integration import IAMIntegration
from labelbox.schema.resource_tag import ResourceTag
from labelbox.schema.project_resource_tag import ProjectResourceTag
from labelbox.schema.media_type import MediaType
11 changes: 11 additions & 0 deletions labelbox/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
from labelbox.schema.project import Project
from labelbox.schema.role import Role

from labelbox.schema.media_type import MediaType

logger = logging.getLogger(__name__)

_LABELBOX_API_KEY = "LABELBOX_API_KEY"
Expand Down Expand Up @@ -611,6 +613,15 @@ def create_project(self, **kwargs) -> Project:
InvalidAttributeError: If the Project type does not contain
any of the attribute names given in kwargs.
"""
media_type = kwargs.get("media_type")
if media_type:
if MediaType.is_supported(media_type):
kwargs["media_type"] = media_type.value
else:
raise TypeError(f"{media_type} is not a valid media type. Use"
f" any of {MediaType.get_supported_members()}"
" from MediaType. Example: MediaType.Image.")

return self._create(Entity.Project, kwargs)

def get_roles(self) -> List[Role]:
Expand Down
2 changes: 1 addition & 1 deletion labelbox/orm/db_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def _set_field_values(self, field_values):
"Failed to convert value '%s' to datetime for "
"field %s", value, field)
elif isinstance(field.field_type, Field.EnumType):
value = field.field_type.enum_cls[value]
value = field.field_type.enum_cls(value)
setattr(self, field.name, value)

def __repr__(self):
Expand Down
1 change: 1 addition & 0 deletions labelbox/schema/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
import labelbox.schema.data_row_metadata
import labelbox.schema.batch
import labelbox.schema.iam_integration
import labelbox.schema.media_type
46 changes: 46 additions & 0 deletions labelbox/schema/media_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from enum import Enum


class MediaType(Enum):
"""add DOCUMENT, GEOSPATIAL_TILE, SIMPLE_TILE to match the UI choices"""
Audio = "AUDIO"
Conversational = "CONVERSATIONAL"
Dicom = "DICOM"
Document = "PDF"
Geospatial_Tile = "TMS_GEO"
Image = "IMAGE"
Json = "JSON"
Pdf = "PDF"
Simple_Tile = "TMS_SIMPLE"
Text = "TEXT"
Tms_Geo = "TMS_GEO"
Tms_Simple = "TMS_SIMPLE"
Video = "VIDEO"
Unknown = "UNKNOWN"
Unsupported = "UNSUPPORTED"

@classmethod
def _missing_(cls, name):
"""Handle missing null data types for projects
created without setting allowedMediaType
Handle upper case names for compatibility with
the GraphQL"""

if name is None:
return cls.Unknown

for member in cls.__members__:
if member.name == name.upper():
return member

@classmethod
def is_supported(cls, value):
return isinstance(value,
cls) and value not in [cls.Unknown, cls.Unsupported]

@classmethod
def get_supported_members(cls):
return [
item for item in cls.__members__
if item not in ["Unknown", "Unsupported"]
]
17 changes: 15 additions & 2 deletions labelbox/schema/project.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import enum
from enum import Enum
import json
import logging
import time
Expand All @@ -19,6 +19,7 @@
from labelbox.orm.model import Entity, Field, Relationship
from labelbox.pagination import PaginatedCollection
from labelbox.schema.resource_tag import ResourceTag
from labelbox.schema.media_type import MediaType

if TYPE_CHECKING:
from labelbox import BulkImportRequest
Expand Down Expand Up @@ -63,6 +64,7 @@ class Project(DbObject, Updateable, Deletable):
benchmarks (Relationship): `ToMany` relationship to Benchmark
ontology (Relationship): `ToOne` relationship to Ontology
"""

name = Field.String("name")
description = Field.String("description")
updated_at = Field.DateTime("updated_at")
Expand All @@ -71,6 +73,8 @@ class Project(DbObject, Updateable, Deletable):
last_activity_time = Field.DateTime("last_activity_time")
auto_audit_number_of_labels = Field.Int("auto_audit_number_of_labels")
auto_audit_percentage = Field.Float("auto_audit_percentage")
# Bind data_type and allowedMediaTYpe using the GraphQL type MediaType
media_type = Field.Enum(MediaType, "media_type", "allowedMediaType")

# Relationships
datasets = Relationship.ToMany("Dataset", True)
Expand All @@ -85,7 +89,7 @@ class Project(DbObject, Updateable, Deletable):
benchmarks = Relationship.ToMany("Benchmark", False)
ontology = Relationship.ToOne("Ontology", True)

class QueueMode(enum.Enum):
class QueueMode(Enum):
Batch = "Batch"
Dataset = "Dataset"

Expand All @@ -94,6 +98,15 @@ def update(self, **kwargs):
if mode:
self._update_queue_mode(mode)

media_type = kwargs.get("media_type")
if media_type:
if MediaType.is_supported(media_type):
kwargs["media_type"] = media_type.value
else:
raise TypeError(f"{media_type} is not a valid media type. Use"
f" any of {MediaType.get_supported_members()}"
" from MediaType. Example: MediaType.Image.")

return super().update(**kwargs)

def members(self) -> PaginatedCollection:
Expand Down
21 changes: 20 additions & 1 deletion tests/integration/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from labelbox import Project, LabelingFrontend, Dataset
from labelbox.exceptions import InvalidQueryError
from labelbox.schema.media_type import MediaType


def test_project(client, rand_gen):
Expand Down Expand Up @@ -219,4 +220,22 @@ def test_batches(configured_project: Project, dataset: Dataset, image_url):
configured_project.create_batch(batch_two, [data_rows[1]])

names = set([batch.name for batch in list(configured_project.batches())])
assert names == set([batch_one, batch_two])
assert names == set([batch_one, batch_two])


def test_media_type(client, configured_project: Project, rand_gen):
# Existing project with no media_type
assert isinstance(configured_project.media_type, MediaType)

# Update test
project = client.create_project(name=rand_gen(str))
project.update(media_type=MediaType.Image)
assert project.media_type == MediaType.Image
project.delete()

for media_type in MediaType.get_supported_members():

project = client.create_project(name=rand_gen(str),
media_type=MediaType[media_type])
assert project.media_type == MediaType[media_type]
project.delete()