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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

# Version 3.21.0
## Added
* Projects can be created with a `media_type`
* Added `media_type` attribute to `Project`
* New `MediaType` enumeration

## Fix
* Added back the mimetype to datarow bulk uploads for orgs that require delegated access

# Version 3.20.1 (2022-05-02)
## Updated
* Ontology Classification `scope` field is only set for top level classifications
Expand Down
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
}
}
5 changes: 3 additions & 2 deletions labelbox/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name = "labelbox"
__version__ = "3.20.1"
__version__ = "3.21.0"

import sys
import warnings

if sys.version_info < (3, 7):
warnings.warn("""Python 3.6 will no longer be actively supported
warnings.warn("""Python 3.6 will no longer be actively supported
starting 06/01/2022. Please upgrade to Python 3.7 or higher.""")

from labelbox.client import Client
Expand Down 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
4 changes: 3 additions & 1 deletion labelbox/schema/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ def convert_item(item):
items = [future.result() for future in as_completed(futures)]
# Prepare and upload the desciptor file
data = json.dumps(items)
return self.client.upload_data(data)
return self.client.upload_data(data,
content_type="application/json",
filename="json_import.json")

def data_rows_for_external_id(self,
external_id,
Expand Down
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"]
]
Loading