Skip to content

Commit b3efc51

Browse files
[SDK-503] Prevent users from uploading video annotations over the API limit (5000). (#1347)
1 parent e7836b9 commit b3efc51

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

labelbox/schema/annotation_import.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from labelbox.types import Label
2424

2525
NDJSON_MIME_TYPE = "application/x-ndjson"
26+
LABEL_LIMIT = 5000
2627
logger = logging.getLogger(__name__)
2728

2829

@@ -153,6 +154,9 @@ def _get_ndjson_from_objects(cls, objects: Union[List[Dict[str, Any]],
153154
)
154155

155156
objects = serialize_labels(objects)
157+
if len(objects) > LABEL_LIMIT:
158+
raise ValueError(
159+
f"Label count {len(objects)} exceeds limit of {(LABEL_LIMIT)}")
156160
cls._validate_data_rows(objects)
157161

158162
data_str = parser.dumps(objects)
@@ -502,8 +506,8 @@ def create_from_objects(
502506
Returns:
503507
MALPredictionImport
504508
"""
505-
data = cls._get_ndjson_from_objects(predictions, 'annotations')
506509

510+
data = cls._get_ndjson_from_objects(predictions, 'annotations')
507511
if len(predictions) > 0 and isinstance(predictions[0], Dict):
508512
predictions_dicts = cast(List[Dict[str, Any]], predictions)
509513
has_confidence = LabelsConfidencePresenceChecker.check(

tests/integration/annotation_import/test_bulk_import_request.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,69 @@ def test_nested_video_object_annotations(client,
370370
import_annotations.wait_until_done()
371371

372372
assert import_annotations.errors == []
373+
374+
375+
def test_below_annotation_limit_on_single_data_row(
376+
client, configured_project_with_one_data_row, video_data, rand_gen):
377+
_, data_row_uids = video_data
378+
379+
def create_label():
380+
return Label(data=VideoData(uid=data_row_uids[0]),
381+
annotations=[
382+
VideoObjectAnnotation(name="bbox",
383+
keyframe=True,
384+
frame=4,
385+
segment_index=0,
386+
value=Rectangle(
387+
start=Point(x=100, y=100),
388+
end=Point(x=105, y=105),
389+
))
390+
])
391+
392+
configured_project_with_one_data_row.update(media_type=MediaType.Video)
393+
configured_project_with_one_data_row.create_batch(
394+
rand_gen(str),
395+
data_row_uids, # sample of data row objects
396+
5 # priority between 1(Highest) - 5(lowest)
397+
)
398+
labels = [create_label() for _ in range(5000)]
399+
import_annotations = MALPredictionImport.create_from_objects(
400+
client=client,
401+
project_id=configured_project_with_one_data_row.uid,
402+
name=f"import {str(uuid.uuid4())}",
403+
predictions=labels)
404+
import_annotations.wait_until_done()
405+
406+
assert import_annotations.errors == []
407+
408+
409+
def test_above_annotation_limit_on_single_data_row(
410+
client, configured_project_with_one_data_row, video_data, rand_gen):
411+
_, data_row_uids = video_data
412+
413+
def create_label():
414+
return Label(data=VideoData(uid=data_row_uids[0]),
415+
annotations=[
416+
VideoObjectAnnotation(name="bbox",
417+
keyframe=True,
418+
frame=4,
419+
segment_index=0,
420+
value=Rectangle(
421+
start=Point(x=100, y=100),
422+
end=Point(x=105, y=105),
423+
))
424+
])
425+
426+
configured_project_with_one_data_row.update(media_type=MediaType.Video)
427+
configured_project_with_one_data_row.create_batch(
428+
rand_gen(str),
429+
data_row_uids, # sample of data row objects
430+
5 # priority between 1(Highest) - 5(lowest)
431+
)
432+
labels = [create_label() for _ in range(5001)]
433+
with pytest.raises(ValueError):
434+
MALPredictionImport.create_from_objects(
435+
client=client,
436+
project_id=configured_project_with_one_data_row.uid,
437+
name=f"import {str(uuid.uuid4())}",
438+
predictions=labels)

0 commit comments

Comments
 (0)