Skip to content

Commit 356faaa

Browse files
authored
Merge pull request #567 from Labelbox/develop
3.21.0
2 parents c0d5064 + 019ec7d commit 356faaa

File tree

11 files changed

+174
-50
lines changed

11 files changed

+174
-50
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
# Version 3.21.0
4+
## Added
5+
* Projects can be created with a `media_type`
6+
* Added `media_type` attribute to `Project`
7+
* New `MediaType` enumeration
8+
9+
## Fix
10+
* Added back the mimetype to datarow bulk uploads for orgs that require delegated access
11+
312
# Version 3.20.1 (2022-05-02)
413
## Updated
514
* Ontology Classification `scope` field is only set for top level classifications

examples/basics/projects.ipynb

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22
"cells": [
33
{
44
"cell_type": "markdown",
5+
"metadata": {},
56
"source": [
67
"<td>\n",
78
" <a target=\"_blank\" href=\"https://labelbox.com\" ><img src=\"https://labelbox.com/blog/content/images/2021/02/logo-v4.svg\" width=256/></a>\n",
89
"</td>"
9-
],
10-
"metadata": {}
10+
]
1111
},
1212
{
1313
"cell_type": "markdown",
14+
"metadata": {},
1415
"source": [
1516
"<td>\n",
1617
"<a href=\"https://colab.research.google.com/github/Labelbox/labelbox-python/blob/develop/examples/basics/projects.ipynb\" target=\"_blank\"><img\n",
@@ -21,18 +22,18 @@
2122
"<a href=\"https://github.com/Labelbox/labelbox-python/tree/develop/examples/basics/projects.ipynb\" target=\"_blank\"><img\n",
2223
"src=\"https://img.shields.io/badge/GitHub-100000?logo=github&logoColor=white\" alt=\"GitHub\"></a>\n",
2324
"</td>"
24-
],
25-
"metadata": {}
25+
]
2626
},
2727
{
2828
"cell_type": "markdown",
29+
"metadata": {},
2930
"source": [
3031
"# Projects"
31-
],
32-
"metadata": {}
32+
]
3333
},
3434
{
3535
"cell_type": "markdown",
36+
"metadata": {},
3637
"source": [
3738
"* A project can be thought of as a specific labeling task on a set of labels\n",
3839
"* That set of labels is defined by the datasets attached to the project\n",
@@ -41,123 +42,129 @@
4142
"\n",
4243
"** Note that there is a lot of advanced usage that is not covered in this notebook. See project_setup for those functions.\n",
4344
"* Also note that deprecated functions are not explained here."
44-
],
45-
"metadata": {}
45+
]
4646
},
4747
{
4848
"cell_type": "code",
4949
"execution_count": 1,
50+
"metadata": {},
51+
"outputs": [],
5052
"source": [
5153
"!pip install labelbox"
52-
],
53-
"outputs": [],
54-
"metadata": {}
54+
]
5555
},
5656
{
5757
"cell_type": "code",
5858
"execution_count": 2,
59+
"metadata": {},
60+
"outputs": [],
5961
"source": [
6062
"from labelbox import Client\n",
63+
"from labelbox.schema.media_type import MediaType\n",
6164
"import os"
62-
],
63-
"outputs": [],
64-
"metadata": {}
65+
]
6566
},
6667
{
6768
"cell_type": "markdown",
69+
"metadata": {},
6870
"source": [
6971
"# API Key and Client\n",
7072
"Provide a valid api key below in order to properly connect to the Labelbox Client."
71-
],
72-
"metadata": {}
73+
]
7374
},
7475
{
7576
"cell_type": "code",
7677
"execution_count": 5,
78+
"metadata": {},
79+
"outputs": [],
7780
"source": [
7881
"# Add your api key\n",
7982
"API_KEY = None\n",
8083
"client = Client(api_key=API_KEY)"
81-
],
82-
"outputs": [],
83-
"metadata": {}
84+
]
8485
},
8586
{
8687
"cell_type": "markdown",
88+
"metadata": {},
8789
"source": [
8890
"### Create\n"
89-
],
90-
"metadata": {}
91+
]
9192
},
9293
{
9394
"cell_type": "code",
9495
"execution_count": 6,
96+
"metadata": {},
97+
"outputs": [],
9598
"source": [
96-
"# Creates an empty project\n",
99+
"# Creates an empty project without a media type\n",
97100
"project = client.create_project(name=\"my-test-project\",\n",
98-
" description=\"a description\")"
99-
],
100-
"outputs": [],
101-
"metadata": {}
101+
" description=\"a description\")\n",
102+
"\n",
103+
"# Creates an empty project a media type\n",
104+
"project = client.create_project(name=\"my-test-project\",\n",
105+
" description=\"a description\",\n",
106+
" media_type=MediaType.Image)"
107+
]
102108
},
103109
{
104110
"cell_type": "markdown",
111+
"metadata": {},
105112
"source": [
106113
"### Read"
107-
],
108-
"metadata": {}
114+
]
109115
},
110116
{
111117
"cell_type": "code",
112118
"execution_count": null,
119+
"metadata": {},
120+
"outputs": [],
113121
"source": [
114122
"# Note the project is not setup (so a lot of these fiels are empty). Follow the project setup workflow\n",
115123
"print(\"Project is not setup yet:\", project.setup_complete is None)\n",
116124
"print(\"Project name:\", project.name)\n",
117125
"print(\"Project description:\", project.description)\n",
126+
"print(\"Media Type:\", project.media_type)\n",
118127
"print(\"Dataset:\", list(project.datasets()))\n",
119128
"print(\"Ontology:\", project.ontology().normalized)\n",
120129
"print(\"Benchmarks:\", project.benchmarks())"
121-
],
122-
"outputs": [],
123-
"metadata": {}
130+
]
124131
},
125132
{
126133
"cell_type": "markdown",
134+
"metadata": {},
127135
"source": [
128136
"### Update\n",
129137
"\n"
130-
],
131-
"metadata": {}
138+
]
132139
},
133140
{
134141
"cell_type": "code",
135142
"execution_count": null,
143+
"metadata": {},
144+
"outputs": [],
136145
"source": [
137146
"# Attach dataset\n",
138147
"ds = client.create_dataset(name=\"test-ds\")\n",
139148
"project.datasets.connect(ds)\n",
140149
"print([ds.name for ds in project.datasets()])\n",
141150
"ds.delete()"
142-
],
143-
"outputs": [],
144-
"metadata": {}
151+
]
145152
},
146153
{
147154
"cell_type": "markdown",
155+
"metadata": {},
148156
"source": [
149157
"### Delete"
150-
],
151-
"metadata": {}
158+
]
152159
},
153160
{
154161
"cell_type": "code",
155162
"execution_count": 9,
163+
"metadata": {},
164+
"outputs": [],
156165
"source": [
157166
"project.delete()"
158-
],
159-
"outputs": [],
160-
"metadata": {}
167+
]
161168
}
162169
],
163170
"metadata": {
@@ -181,4 +188,4 @@
181188
},
182189
"nbformat": 4,
183190
"nbformat_minor": 5
184-
}
191+
}

labelbox/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
name = "labelbox"
2-
__version__ = "3.20.1"
2+
__version__ = "3.21.0"
33

44
import sys
55
import warnings
66

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

1111
from labelbox.client import Client
@@ -33,3 +33,4 @@
3333
from labelbox.schema.iam_integration import IAMIntegration
3434
from labelbox.schema.resource_tag import ResourceTag
3535
from labelbox.schema.project_resource_tag import ProjectResourceTag
36+
from labelbox.schema.media_type import MediaType

labelbox/client.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
from labelbox.schema.project import Project
3333
from labelbox.schema.role import Role
3434

35+
from labelbox.schema.media_type import MediaType
36+
3537
logger = logging.getLogger(__name__)
3638

3739
_LABELBOX_API_KEY = "LABELBOX_API_KEY"
@@ -611,6 +613,15 @@ def create_project(self, **kwargs) -> Project:
611613
InvalidAttributeError: If the Project type does not contain
612614
any of the attribute names given in kwargs.
613615
"""
616+
media_type = kwargs.get("media_type")
617+
if media_type:
618+
if MediaType.is_supported(media_type):
619+
kwargs["media_type"] = media_type.value
620+
else:
621+
raise TypeError(f"{media_type} is not a valid media type. Use"
622+
f" any of {MediaType.get_supported_members()}"
623+
" from MediaType. Example: MediaType.Image.")
624+
614625
return self._create(Entity.Project, kwargs)
615626

616627
def get_roles(self) -> List[Role]:

labelbox/orm/db_object.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def _set_field_values(self, field_values):
6969
"Failed to convert value '%s' to datetime for "
7070
"field %s", value, field)
7171
elif isinstance(field.field_type, Field.EnumType):
72-
value = field.field_type.enum_cls[value]
72+
value = field.field_type.enum_cls(value)
7373
setattr(self, field.name, value)
7474

7575
def __repr__(self):

labelbox/schema/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@
2020
import labelbox.schema.data_row_metadata
2121
import labelbox.schema.batch
2222
import labelbox.schema.iam_integration
23+
import labelbox.schema.media_type

labelbox/schema/dataset.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,9 @@ def convert_item(item):
314314
items = [future.result() for future in as_completed(futures)]
315315
# Prepare and upload the desciptor file
316316
data = json.dumps(items)
317-
return self.client.upload_data(data)
317+
return self.client.upload_data(data,
318+
content_type="application/json",
319+
filename="json_import.json")
318320

319321
def data_rows_for_external_id(self,
320322
external_id,

labelbox/schema/media_type.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from enum import Enum
2+
3+
4+
class MediaType(Enum):
5+
"""add DOCUMENT, GEOSPATIAL_TILE, SIMPLE_TILE to match the UI choices"""
6+
Audio = "AUDIO"
7+
Conversational = "CONVERSATIONAL"
8+
Dicom = "DICOM"
9+
Document = "PDF"
10+
Geospatial_Tile = "TMS_GEO"
11+
Image = "IMAGE"
12+
Json = "JSON"
13+
Pdf = "PDF"
14+
Simple_Tile = "TMS_SIMPLE"
15+
Text = "TEXT"
16+
Tms_Geo = "TMS_GEO"
17+
Tms_Simple = "TMS_SIMPLE"
18+
Video = "VIDEO"
19+
Unknown = "UNKNOWN"
20+
Unsupported = "UNSUPPORTED"
21+
22+
@classmethod
23+
def _missing_(cls, name):
24+
"""Handle missing null data types for projects
25+
created without setting allowedMediaType
26+
Handle upper case names for compatibility with
27+
the GraphQL"""
28+
29+
if name is None:
30+
return cls.Unknown
31+
32+
for member in cls.__members__:
33+
if member.name == name.upper():
34+
return member
35+
36+
@classmethod
37+
def is_supported(cls, value):
38+
return isinstance(value,
39+
cls) and value not in [cls.Unknown, cls.Unsupported]
40+
41+
@classmethod
42+
def get_supported_members(cls):
43+
return [
44+
item for item in cls.__members__
45+
if item not in ["Unknown", "Unsupported"]
46+
]

0 commit comments

Comments
 (0)