Skip to content

Commit 26a35fd

Browse files
chore: lint
1 parent c2a7b4c commit 26a35fd

File tree

8 files changed

+241
-161
lines changed

8 files changed

+241
-161
lines changed

libs/labelbox/src/labelbox/data/annotation_types/audio.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
from typing import Optional
22

3-
from labelbox.data.annotation_types.annotation import ClassificationAnnotation, ObjectAnnotation
4-
from labelbox.data.mixins import ConfidenceNotSupportedMixin, CustomMetricsNotSupportedMixin
3+
from labelbox.data.annotation_types.annotation import (
4+
ClassificationAnnotation,
5+
ObjectAnnotation,
6+
)
7+
from labelbox.data.mixins import (
8+
ConfidenceNotSupportedMixin,
9+
CustomMetricsNotSupportedMixin,
10+
)
511

612

713
class AudioClassificationAnnotation(ClassificationAnnotation):
814
"""Audio classification for specific time range
9-
15+
1016
Examples:
1117
- Speaker identification from 2500ms to 4100ms
1218
- Audio quality assessment for a segment
1319
- Language detection for audio segments
14-
20+
1521
Args:
1622
name (Optional[str]): Name of the classification
1723
feature_schema_id (Optional[Cuid]): Feature schema identifier
@@ -27,14 +33,18 @@ class AudioClassificationAnnotation(ClassificationAnnotation):
2733
segment_index: Optional[int] = None
2834

2935

30-
class AudioObjectAnnotation(ObjectAnnotation, ConfidenceNotSupportedMixin, CustomMetricsNotSupportedMixin):
36+
class AudioObjectAnnotation(
37+
ObjectAnnotation,
38+
ConfidenceNotSupportedMixin,
39+
CustomMetricsNotSupportedMixin,
40+
):
3141
"""Audio object annotation for specific time range
32-
42+
3343
Examples:
3444
- Transcription: "Hello world" from 2500ms to 4100ms
3545
- Sound events: "Dog barking" from 10000ms to 12000ms
3646
- Audio segments with metadata
37-
47+
3848
Args:
3949
name (Optional[str]): Name of the annotation
4050
feature_schema_id (Optional[Cuid]): Feature schema identifier

libs/labelbox/src/labelbox/data/annotation_types/label.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,14 @@ def frame_annotations(
9090

9191
def audio_annotations_by_frame(
9292
self,
93-
) -> Dict[int, List[Union[AudioObjectAnnotation, AudioClassificationAnnotation]]]:
93+
) -> Dict[
94+
int, List[Union[AudioObjectAnnotation, AudioClassificationAnnotation]]
95+
]:
9496
"""Get audio annotations organized by frame (millisecond)
95-
97+
9698
Returns:
9799
Dict[int, List]: Dictionary mapping frame (milliseconds) to list of audio annotations
98-
100+
99101
Example:
100102
>>> label.audio_annotations_by_frame()
101103
{2500: [AudioClassificationAnnotation(...)], 10000: [AudioObjectAnnotation(...)]}

libs/labelbox/src/labelbox/data/serialization/ndjson/classification.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,11 @@ class NDClassification:
401401
@staticmethod
402402
def to_common(
403403
annotation: "NDClassificationType",
404-
) -> Union[ClassificationAnnotation, VideoClassificationAnnotation]:
404+
) -> Union[
405+
ClassificationAnnotation,
406+
VideoClassificationAnnotation,
407+
AudioClassificationAnnotation,
408+
]:
405409
common = ClassificationAnnotation(
406410
value=annotation.to_common(),
407411
name=annotation.name,
@@ -416,18 +420,35 @@ def to_common(
416420
results = []
417421
for frame in annotation.frames:
418422
for idx in range(frame.start, frame.end + 1, 1):
419-
results.append(
420-
VideoClassificationAnnotation(
421-
frame=idx, **common.model_dump(exclude_none=True)
423+
# Check if this is an audio annotation by looking at the extra data
424+
# Audio annotations will have frame/end_frame in extra, video annotations won't
425+
if (
426+
hasattr(annotation, "extra")
427+
and annotation.extra
428+
and "frames" in annotation.extra
429+
):
430+
# This is likely an audio temporal annotation
431+
results.append(
432+
AudioClassificationAnnotation(
433+
frame=idx, **common.model_dump(exclude_none=True)
434+
)
435+
)
436+
else:
437+
# This is a video temporal annotation
438+
results.append(
439+
VideoClassificationAnnotation(
440+
frame=idx, **common.model_dump(exclude_none=True)
441+
)
422442
)
423-
)
424443
return results
425444

426445
@classmethod
427446
def from_common(
428447
cls,
429448
annotation: Union[
430-
ClassificationAnnotation, VideoClassificationAnnotation, AudioClassificationAnnotation
449+
ClassificationAnnotation,
450+
VideoClassificationAnnotation,
451+
AudioClassificationAnnotation,
431452
],
432453
data: GenericDataRowData,
433454
) -> Union[NDTextSubclass, NDChecklistSubclass, NDRadioSubclass]:
@@ -450,7 +471,9 @@ def from_common(
450471
@staticmethod
451472
def lookup_classification(
452473
annotation: Union[
453-
ClassificationAnnotation, VideoClassificationAnnotation, AudioClassificationAnnotation
474+
ClassificationAnnotation,
475+
VideoClassificationAnnotation,
476+
AudioClassificationAnnotation,
454477
],
455478
) -> Union[NDText, NDChecklist, NDRadio]:
456479
return {Text: NDText, Checklist: NDChecklist, Radio: NDRadio}.get(

libs/labelbox/src/labelbox/data/serialization/ndjson/label.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,17 +171,17 @@ def _create_audio_annotations(
171171
cls, label: Label
172172
) -> Generator[Union[NDChecklistSubclass, NDRadioSubclass], None, None]:
173173
"""Create audio annotations using generic temporal processor
174-
174+
175175
Args:
176176
label: Label containing audio annotations to be processed
177-
177+
178178
Yields:
179179
NDClassification or NDObject: Audio annotations in NDJSON format
180180
"""
181181
# Use processor with configurable behavior
182182
processor = AudioTemporalProcessor(
183183
group_text_annotations=True, # Group multiple TEXT annotations into one feature
184-
enable_token_mapping=True # Enable per-keyframe token content
184+
enable_token_mapping=True, # Enable per-keyframe token content
185185
)
186186
yield from processor.process_annotations(label)
187187

@@ -215,7 +215,7 @@ def _create_non_video_annotations(cls, label: Label):
215215
yield NDMessageTask.from_common(annotation, label.data)
216216
else:
217217
raise TypeError(
218-
f"Unable to convert object to MAL format. `{type(getattr(annotation, 'value',annotation))}`"
218+
f"Unable to convert object to MAL format. `{type(getattr(annotation, 'value', annotation))}`"
219219
)
220220

221221
@classmethod

libs/labelbox/src/labelbox/data/serialization/ndjson/objects.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -773,29 +773,31 @@ def from_common(
773773
)
774774

775775
@classmethod
776-
def _serialize_audio_object_annotation(cls, annotation: AudioObjectAnnotation, data: GenericDataRowData):
776+
def _serialize_audio_object_annotation(
777+
cls, annotation: AudioObjectAnnotation, data: GenericDataRowData
778+
):
777779
"""Serialize audio object annotation with temporal information
778-
780+
779781
Args:
780782
annotation: Audio object annotation to process
781783
data: Data row data
782-
784+
783785
Returns:
784786
NDObject: Serialized audio object annotation
785787
"""
786788
# Get the appropriate NDObject subclass based on the annotation value type
787789
obj = cls.lookup_object(annotation)
788-
790+
789791
# Process sub-classifications if any
790792
subclasses = [
791793
NDSubclassification.from_common(annot)
792794
for annot in annotation.classifications
793795
]
794-
796+
795797
# Add frame information to extra (milliseconds)
796798
extra = annotation.extra.copy() if annotation.extra else {}
797799
extra.update({"frame": annotation.frame})
798-
800+
799801
# Create the NDObject with frame information
800802
return obj.from_common(
801803
str(annotation._uuid),
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# Utils package for NDJSON serialization helpers
1+
# Utils package for NDJSON serialization helpers

0 commit comments

Comments
 (0)