label-studio-sdk 1.0.0__py3-none-any.whl → 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- label_studio_sdk/__init__.py +46 -4
- label_studio_sdk/_extensions/pager_ext.py +49 -0
- label_studio_sdk/_legacy/schema/label_config_schema.json +14 -14
- label_studio_sdk/actions/__init__.py +27 -0
- label_studio_sdk/actions/client.py +129 -8
- label_studio_sdk/actions/types/__init__.py +27 -0
- label_studio_sdk/actions/types/actions_create_request_filters.py +43 -0
- label_studio_sdk/actions/types/actions_create_request_filters_conjunction.py +5 -0
- label_studio_sdk/actions/types/actions_create_request_filters_items_item.py +50 -0
- label_studio_sdk/actions/types/actions_create_request_filters_items_item_filter.py +31 -0
- label_studio_sdk/actions/types/actions_create_request_filters_items_item_operator.py +23 -0
- label_studio_sdk/actions/types/actions_create_request_filters_items_item_value.py +5 -0
- label_studio_sdk/actions/types/actions_create_request_id.py +19 -0
- label_studio_sdk/actions/types/actions_create_request_ordering_item.py +31 -0
- label_studio_sdk/actions/types/actions_create_request_selected_items.py +10 -0
- label_studio_sdk/actions/types/actions_create_request_selected_items_excluded.py +39 -0
- label_studio_sdk/actions/types/actions_create_request_selected_items_included.py +39 -0
- label_studio_sdk/base_client.py +183 -0
- label_studio_sdk/client.py +17 -175
- label_studio_sdk/core/client_wrapper.py +1 -1
- label_studio_sdk/core/http_client.py +5 -1
- label_studio_sdk/errors/bad_request_error.py +3 -1
- label_studio_sdk/export_storage/azure/client.py +176 -10
- label_studio_sdk/export_storage/azure/types/azure_create_response.py +15 -0
- label_studio_sdk/export_storage/azure/types/azure_update_response.py +15 -0
- label_studio_sdk/export_storage/gcs/client.py +180 -14
- label_studio_sdk/export_storage/gcs/types/gcs_create_response.py +16 -1
- label_studio_sdk/export_storage/gcs/types/gcs_update_response.py +16 -1
- label_studio_sdk/export_storage/local/client.py +168 -22
- label_studio_sdk/export_storage/local/types/local_create_response.py +12 -2
- label_studio_sdk/export_storage/local/types/local_update_response.py +12 -2
- label_studio_sdk/export_storage/redis/client.py +234 -30
- label_studio_sdk/export_storage/redis/types/redis_create_response.py +20 -5
- label_studio_sdk/export_storage/redis/types/redis_update_response.py +20 -5
- label_studio_sdk/export_storage/s3/client.py +214 -26
- label_studio_sdk/export_storage/s3/types/s3create_response.py +15 -0
- label_studio_sdk/export_storage/s3/types/s3update_response.py +15 -0
- label_studio_sdk/import_storage/azure/client.py +266 -90
- label_studio_sdk/import_storage/azure/types/azure_create_response.py +28 -18
- label_studio_sdk/import_storage/azure/types/azure_update_response.py +28 -18
- label_studio_sdk/import_storage/gcs/client.py +270 -94
- label_studio_sdk/import_storage/gcs/types/gcs_create_response.py +28 -18
- label_studio_sdk/import_storage/gcs/types/gcs_update_response.py +28 -18
- label_studio_sdk/import_storage/local/client.py +168 -22
- label_studio_sdk/import_storage/local/types/local_create_response.py +12 -2
- label_studio_sdk/import_storage/local/types/local_update_response.py +12 -2
- label_studio_sdk/import_storage/redis/client.py +206 -50
- label_studio_sdk/import_storage/redis/types/redis_create_response.py +20 -10
- label_studio_sdk/import_storage/redis/types/redis_update_response.py +20 -10
- label_studio_sdk/import_storage/s3/client.py +336 -110
- label_studio_sdk/import_storage/s3/types/s3create_response.py +35 -25
- label_studio_sdk/import_storage/s3/types/s3update_response.py +35 -25
- label_studio_sdk/{_legacy/label_interface → label_interface}/base.py +10 -0
- label_studio_sdk/{_legacy/label_interface → label_interface}/control_tags.py +109 -71
- label_studio_sdk/{_legacy/label_interface → label_interface}/interface.py +97 -51
- label_studio_sdk/{_legacy/label_interface → label_interface}/object_tags.py +8 -13
- label_studio_sdk/label_interface/objects.py +60 -0
- label_studio_sdk/label_interface/region.py +75 -0
- label_studio_sdk/projects/client.py +6 -4
- label_studio_sdk/projects/client_ext.py +19 -0
- label_studio_sdk/tasks/client.py +35 -8
- label_studio_sdk/tasks/client_ext.py +18 -0
- label_studio_sdk/types/__init__.py +10 -0
- label_studio_sdk/types/annotation.py +5 -5
- label_studio_sdk/types/annotations_dm_field.py +120 -0
- label_studio_sdk/types/annotations_dm_field_last_action.py +19 -0
- label_studio_sdk/types/data_manager_task_serializer.py +123 -0
- label_studio_sdk/types/data_manager_task_serializer_drafts_item.py +31 -0
- label_studio_sdk/types/data_manager_task_serializer_predictions_item.py +37 -0
- label_studio_sdk/types/task.py +1 -1
- label_studio_sdk/views/__init__.py +12 -4
- label_studio_sdk/views/types/__init__.py +12 -4
- label_studio_sdk/views/types/views_create_request_data.py +2 -2
- label_studio_sdk/views/types/views_create_request_data_filters.py +5 -5
- label_studio_sdk/views/types/views_create_request_data_filters_conjunction.py +1 -1
- label_studio_sdk/views/types/views_create_request_data_filters_items_item.py +11 -8
- label_studio_sdk/views/types/views_create_request_data_filters_items_item_filter.py +31 -0
- label_studio_sdk/views/types/views_create_request_data_filters_items_item_operator.py +23 -0
- label_studio_sdk/views/types/views_create_request_data_filters_items_item_value.py +5 -0
- label_studio_sdk/views/types/views_create_request_data_ordering_item.py +27 -34
- label_studio_sdk/views/types/views_update_request_data.py +2 -2
- label_studio_sdk/views/types/views_update_request_data_filters.py +5 -5
- label_studio_sdk/views/types/views_update_request_data_filters_conjunction.py +1 -1
- label_studio_sdk/views/types/views_update_request_data_filters_items_item.py +11 -8
- label_studio_sdk/views/types/views_update_request_data_filters_items_item_filter.py +31 -0
- label_studio_sdk/views/types/views_update_request_data_filters_items_item_operator.py +23 -0
- label_studio_sdk/views/types/views_update_request_data_filters_items_item_value.py +5 -0
- label_studio_sdk/views/types/views_update_request_data_ordering_item.py +27 -34
- label_studio_sdk-1.0.2.dist-info/METADATA +195 -0
- {label_studio_sdk-1.0.0.dist-info → label_studio_sdk-1.0.2.dist-info}/RECORD +94 -69
- label_studio_sdk/_legacy/label_interface/region.py +0 -43
- label_studio_sdk/_legacy/objects.py +0 -35
- label_studio_sdk/views/types/views_create_request_data_ordering_item_direction.py +0 -5
- label_studio_sdk/views/types/views_update_request_data_ordering_item_direction.py +0 -5
- label_studio_sdk-1.0.0.dist-info/METADATA +0 -307
- /label_studio_sdk/{_legacy/label_interface → label_interface}/__init__.py +0 -0
- /label_studio_sdk/{_legacy/label_interface → label_interface}/data_examples.json +0 -0
- /label_studio_sdk/{_legacy/label_interface → label_interface}/label_tags.py +0 -0
- {label_studio_sdk-1.0.0.dist-info → label_studio_sdk-1.0.2.dist-info}/WHEEL +0 -0
|
@@ -8,29 +8,54 @@ from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class S3CreateResponse(pydantic_v1.BaseModel):
|
|
11
|
-
|
|
11
|
+
regex_filter: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
12
12
|
"""
|
|
13
|
-
|
|
13
|
+
Cloud storage regex for filtering objects. You must specify it otherwise no objects will be imported.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
use_blob_urls: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
17
17
|
"""
|
|
18
|
-
|
|
18
|
+
Interpret objects as BLOBs and generate URLs. For example, if your bucket contains images, you can use this option to generate URLs for these images. If set to False, it will read the content of the file and load it into Label Studio.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
presign: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
22
22
|
"""
|
|
23
|
-
|
|
23
|
+
Presign URLs for download
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
presign_ttl: typing.Optional[int] = pydantic_v1.Field(default=None)
|
|
27
27
|
"""
|
|
28
|
-
|
|
28
|
+
Presign TTL in minutes
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
recursive_scan: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
32
|
+
"""
|
|
33
|
+
Scan recursively
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
title: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
37
|
+
"""
|
|
38
|
+
Storage title
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
description: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
42
|
+
"""
|
|
43
|
+
Storage description
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
project: typing.Optional[int] = pydantic_v1.Field(default=None)
|
|
32
47
|
"""
|
|
33
|
-
|
|
48
|
+
Project ID
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
bucket: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
52
|
+
"""
|
|
53
|
+
S3 bucket name
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
prefix: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
57
|
+
"""
|
|
58
|
+
S3 bucket prefix
|
|
34
59
|
"""
|
|
35
60
|
|
|
36
61
|
aws_access_key_id: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
@@ -63,21 +88,6 @@ class S3CreateResponse(pydantic_v1.BaseModel):
|
|
|
63
88
|
S3 Endpoint
|
|
64
89
|
"""
|
|
65
90
|
|
|
66
|
-
presign: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
67
|
-
"""
|
|
68
|
-
Presign URLs for download
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
presign_ttl: typing.Optional[int] = pydantic_v1.Field(default=None)
|
|
72
|
-
"""
|
|
73
|
-
Presign TTL in seconds
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
recursive_scan: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
77
|
-
"""
|
|
78
|
-
Scan recursively
|
|
79
|
-
"""
|
|
80
|
-
|
|
81
91
|
def json(self, **kwargs: typing.Any) -> str:
|
|
82
92
|
kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
|
|
83
93
|
return super().json(**kwargs_with_defaults)
|
|
@@ -8,29 +8,54 @@ from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class S3UpdateResponse(pydantic_v1.BaseModel):
|
|
11
|
-
|
|
11
|
+
regex_filter: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
12
12
|
"""
|
|
13
|
-
|
|
13
|
+
Cloud storage regex for filtering objects. You must specify it otherwise no objects will be imported.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
use_blob_urls: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
17
17
|
"""
|
|
18
|
-
|
|
18
|
+
Interpret objects as BLOBs and generate URLs. For example, if your bucket contains images, you can use this option to generate URLs for these images. If set to False, it will read the content of the file and load it into Label Studio.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
presign: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
22
22
|
"""
|
|
23
|
-
|
|
23
|
+
Presign URLs for download
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
presign_ttl: typing.Optional[int] = pydantic_v1.Field(default=None)
|
|
27
27
|
"""
|
|
28
|
-
|
|
28
|
+
Presign TTL in minutes
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
recursive_scan: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
32
|
+
"""
|
|
33
|
+
Scan recursively
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
title: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
37
|
+
"""
|
|
38
|
+
Storage title
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
description: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
42
|
+
"""
|
|
43
|
+
Storage description
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
project: typing.Optional[int] = pydantic_v1.Field(default=None)
|
|
32
47
|
"""
|
|
33
|
-
|
|
48
|
+
Project ID
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
bucket: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
52
|
+
"""
|
|
53
|
+
S3 bucket name
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
prefix: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
57
|
+
"""
|
|
58
|
+
S3 bucket prefix
|
|
34
59
|
"""
|
|
35
60
|
|
|
36
61
|
aws_access_key_id: typing.Optional[str] = pydantic_v1.Field(default=None)
|
|
@@ -63,21 +88,6 @@ class S3UpdateResponse(pydantic_v1.BaseModel):
|
|
|
63
88
|
S3 Endpoint
|
|
64
89
|
"""
|
|
65
90
|
|
|
66
|
-
presign: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
67
|
-
"""
|
|
68
|
-
Presign URLs for download
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
presign_ttl: typing.Optional[int] = pydantic_v1.Field(default=None)
|
|
72
|
-
"""
|
|
73
|
-
Presign TTL in seconds
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
recursive_scan: typing.Optional[bool] = pydantic_v1.Field(default=None)
|
|
77
|
-
"""
|
|
78
|
-
Scan recursively
|
|
79
|
-
"""
|
|
80
|
-
|
|
81
91
|
def json(self, **kwargs: typing.Any) -> str:
|
|
82
92
|
kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
|
|
83
93
|
return super().json(**kwargs_with_defaults)
|
|
@@ -2,6 +2,16 @@ from pydantic import BaseModel
|
|
|
2
2
|
from typing import Dict, Optional, List, Tuple, Any, Callable
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
def get_tag_class(name, default_mapping, re_mapping=None):
|
|
6
|
+
""" """
|
|
7
|
+
lc_name = name.lower()
|
|
8
|
+
if re_mapping and lc_name in re_mapping:
|
|
9
|
+
return re_mapping.get(lc_name)
|
|
10
|
+
else:
|
|
11
|
+
class_name = default_mapping.get(name.lower())
|
|
12
|
+
return class_name
|
|
13
|
+
|
|
14
|
+
|
|
5
15
|
class LabelStudioTag(BaseModel):
|
|
6
16
|
"""
|
|
7
17
|
Base class for a LabelStudio Tag
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
import xml.etree.ElementTree
|
|
5
5
|
from typing import Type, Dict, Optional, List, Tuple, Any, Union
|
|
6
|
-
from pydantic import BaseModel, confloat
|
|
6
|
+
from pydantic import BaseModel, confloat, Field, validator
|
|
7
7
|
|
|
8
|
-
from .base import LabelStudioTag
|
|
8
|
+
from .base import LabelStudioTag, get_tag_class
|
|
9
9
|
from .region import Region
|
|
10
10
|
from .object_tags import ObjectTag
|
|
11
11
|
|
|
@@ -42,12 +42,6 @@ _TAG_TO_CLASS = {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def get_tag_class(name):
|
|
46
|
-
""" """
|
|
47
|
-
class_name = _TAG_TO_CLASS.get(name.lower())
|
|
48
|
-
return globals().get(class_name, None)
|
|
49
|
-
|
|
50
|
-
|
|
51
45
|
class ControlTag(LabelStudioTag):
|
|
52
46
|
"""
|
|
53
47
|
Class that represents a ControlTag in Label Studio
|
|
@@ -100,7 +94,7 @@ class ControlTag(LabelStudioTag):
|
|
|
100
94
|
)
|
|
101
95
|
|
|
102
96
|
@classmethod
|
|
103
|
-
def parse_node(cls, tag: xml.etree.ElementTree.Element) -> "ControlTag":
|
|
97
|
+
def parse_node(cls, tag: xml.etree.ElementTree.Element, tags_mapping=None) -> "ControlTag":
|
|
104
98
|
"""
|
|
105
99
|
Parse tag into a tag info
|
|
106
100
|
|
|
@@ -114,8 +108,10 @@ class ControlTag(LabelStudioTag):
|
|
|
114
108
|
ControlTag
|
|
115
109
|
The parsed tag
|
|
116
110
|
"""
|
|
117
|
-
tag_class = get_tag_class(tag.tag) or cls
|
|
118
|
-
|
|
111
|
+
tag_class = get_tag_class(tag.tag, _TAG_TO_CLASS, re_mapping=tags_mapping) or cls
|
|
112
|
+
if isinstance(tag_class, str):
|
|
113
|
+
tag_class = globals().get(tag_class, None)
|
|
114
|
+
|
|
119
115
|
tag_info = {
|
|
120
116
|
"tag": tag.tag,
|
|
121
117
|
"name": tag.attrib["name"],
|
|
@@ -142,7 +138,9 @@ class ControlTag(LabelStudioTag):
|
|
|
142
138
|
if conditionals:
|
|
143
139
|
tag_info["conditionals"] = conditionals
|
|
144
140
|
|
|
145
|
-
|
|
141
|
+
val = tag.attrib.get("value", None)
|
|
142
|
+
if (val is not None and len(val) and val[0] == "$") or \
|
|
143
|
+
tag.attrib.get("apiUrl"):
|
|
146
144
|
tag_info["dynamic_value"] = True
|
|
147
145
|
|
|
148
146
|
return tag_class(**tag_info)
|
|
@@ -290,6 +288,7 @@ class ControlTag(LabelStudioTag):
|
|
|
290
288
|
bool
|
|
291
289
|
True if the value is valid, False otherwise
|
|
292
290
|
"""
|
|
291
|
+
|
|
293
292
|
if hasattr(self, "_label_attr_name"):
|
|
294
293
|
if not self._validate_value_labels(value):
|
|
295
294
|
return False
|
|
@@ -361,7 +360,7 @@ class ControlTag(LabelStudioTag):
|
|
|
361
360
|
obj = self.find_object_by_name(to_name)
|
|
362
361
|
cls = self._value_class
|
|
363
362
|
value = cls(**kwargs)
|
|
364
|
-
|
|
363
|
+
|
|
365
364
|
return Region(from_tag=self, to_tag=obj, value=value)
|
|
366
365
|
|
|
367
366
|
def _label_with_labels(
|
|
@@ -419,8 +418,8 @@ class ControlTag(LabelStudioTag):
|
|
|
419
418
|
**kwargs,
|
|
420
419
|
) -> Region:
|
|
421
420
|
"""
|
|
422
|
-
This method creates a new Region object with the specified label
|
|
423
|
-
|
|
421
|
+
This method creates a new Region object with the specified label.
|
|
422
|
+
|
|
424
423
|
If labels are provided, it creates a new instance of the value class with the provided arguments and keyword arguments and adds the labels to the Region object.
|
|
425
424
|
|
|
426
425
|
Parameters:
|
|
@@ -459,13 +458,13 @@ class ControlTag(LabelStudioTag):
|
|
|
459
458
|
|
|
460
459
|
|
|
461
460
|
class SpanSelection(BaseModel):
|
|
462
|
-
start:
|
|
463
|
-
end:
|
|
461
|
+
start: int = Field(..., ge=0)
|
|
462
|
+
end: int = Field(..., ge=0)
|
|
464
463
|
|
|
465
464
|
|
|
466
465
|
class SpanSelectionOffsets(SpanSelection):
|
|
467
|
-
startOffset: int
|
|
468
|
-
endOffset: int
|
|
466
|
+
startOffset: int = Field(..., ge=0)
|
|
467
|
+
endOffset: int = Field(..., ge=0)
|
|
469
468
|
|
|
470
469
|
|
|
471
470
|
class ChoicesValue(BaseModel):
|
|
@@ -492,11 +491,42 @@ class LabelsTag(ControlTag):
|
|
|
492
491
|
|
|
493
492
|
## Image tags
|
|
494
493
|
|
|
494
|
+
def validate_rle(list):
|
|
495
|
+
"""
|
|
496
|
+
Validate if a list is correctly formatted in Run-Length Encoding (RLE).
|
|
497
|
+
|
|
498
|
+
A correctly formatted RLE list should follow 'value, count' pairs.
|
|
499
|
+
For example, [2,3,3,2] is a valid RLE list representing [2,2,2,3,3].
|
|
500
|
+
|
|
501
|
+
Parameters:
|
|
502
|
+
list : a list of integers
|
|
503
|
+
|
|
504
|
+
Returns:
|
|
505
|
+
bool : True if the list is correctly formatted in RLE, False otherwise
|
|
506
|
+
"""
|
|
507
|
+
# If the list length is odd, it's invalid.
|
|
508
|
+
if len(list) % 2 != 0:
|
|
509
|
+
return False
|
|
510
|
+
|
|
511
|
+
# Check 'value, count' pairs. The count should always be greater than zero.
|
|
512
|
+
for i in range(1, len(list), 2):
|
|
513
|
+
if list[i] <= 0:
|
|
514
|
+
return False
|
|
515
|
+
|
|
516
|
+
return True
|
|
517
|
+
|
|
495
518
|
|
|
496
519
|
class BrushValue(BaseModel):
|
|
497
|
-
format: str
|
|
520
|
+
format: str = "rle"
|
|
498
521
|
rle: List[int]
|
|
499
522
|
|
|
523
|
+
@validator('rle')
|
|
524
|
+
def validate_rle(cls, rle_data):
|
|
525
|
+
if not validate_rle(rle_data):
|
|
526
|
+
raise ValueError('Invalid RLE format')
|
|
527
|
+
|
|
528
|
+
return rle_data
|
|
529
|
+
|
|
500
530
|
|
|
501
531
|
class BrushLabelsValue(BrushValue):
|
|
502
532
|
brushlabels: List[str]
|
|
@@ -507,8 +537,14 @@ class BrushTag(ControlTag):
|
|
|
507
537
|
|
|
508
538
|
_value_class: Type[BrushValue] = BrushValue
|
|
509
539
|
|
|
540
|
+
# def validate_value(self, value) -> bool:
|
|
541
|
+
# res = super().validate_value(value)
|
|
542
|
+
# if res is True and value.get("format") == "rle":
|
|
543
|
+
# return validate_rle(value.get("rle"))
|
|
544
|
+
|
|
545
|
+
# return res
|
|
510
546
|
|
|
511
|
-
class BrushLabelsTag(
|
|
547
|
+
class BrushLabelsTag(BrushTag):
|
|
512
548
|
""" """
|
|
513
549
|
|
|
514
550
|
_label_attr_name: str = "brushlabels"
|
|
@@ -520,7 +556,7 @@ class EllipseValue(BaseModel):
|
|
|
520
556
|
y: confloat(le=100)
|
|
521
557
|
radiusX: confloat(le=50)
|
|
522
558
|
radiusY: confloat(le=50)
|
|
523
|
-
rotation: confloat(le=360) = 0
|
|
559
|
+
rotation: Optional[confloat(le=360)] = 0
|
|
524
560
|
|
|
525
561
|
|
|
526
562
|
class EllipseLabelsValue(EllipseValue):
|
|
@@ -563,7 +599,7 @@ class KeyPointLabelsTag(ControlTag):
|
|
|
563
599
|
|
|
564
600
|
|
|
565
601
|
class PolygonValue(BaseModel):
|
|
566
|
-
points: Tuple[confloat(le=100), confloat(le=100)]
|
|
602
|
+
points: List[Tuple[confloat(le=100), confloat(le=100)]]
|
|
567
603
|
|
|
568
604
|
|
|
569
605
|
class PolygonLabelsValue(PolygonValue):
|
|
@@ -575,9 +611,6 @@ class PolygonTag(ControlTag):
|
|
|
575
611
|
|
|
576
612
|
_value_class: Type[PolygonValue] = PolygonValue
|
|
577
613
|
|
|
578
|
-
def label(self, *args, **kwargs):
|
|
579
|
-
""" """
|
|
580
|
-
|
|
581
614
|
|
|
582
615
|
class PolygonLabelsTag(ControlTag):
|
|
583
616
|
""" """
|
|
@@ -591,7 +624,7 @@ class RectangleValue(BaseModel):
|
|
|
591
624
|
y: confloat(le=100)
|
|
592
625
|
width: confloat(le=100)
|
|
593
626
|
height: confloat(le=100)
|
|
594
|
-
rotation: confloat(le=360)
|
|
627
|
+
rotation: Optional[confloat(le=360)] = 0
|
|
595
628
|
|
|
596
629
|
|
|
597
630
|
class RectangleLabelsValue(RectangleValue):
|
|
@@ -611,42 +644,45 @@ class RectangleLabelsTag(ControlTag):
|
|
|
611
644
|
_value_class: Type[RectangleLabelsValue] = RectangleLabelsValue
|
|
612
645
|
|
|
613
646
|
|
|
614
|
-
class
|
|
615
|
-
x:
|
|
616
|
-
y:
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
647
|
+
class VideoRectangleSequenceValue(BaseModel):
|
|
648
|
+
x: confloat(le=100)
|
|
649
|
+
y: confloat(le=100)
|
|
650
|
+
time: float
|
|
651
|
+
frame: int
|
|
652
|
+
width: confloat(le=100)
|
|
653
|
+
height: confloat(le=100)
|
|
654
|
+
rotation: Optional[float] = 0
|
|
620
655
|
|
|
621
656
|
|
|
657
|
+
class VideoRectangleValue(BaseModel):
|
|
658
|
+
framesCount: int
|
|
659
|
+
duration: float
|
|
660
|
+
sequence: List[VideoRectangleSequenceValue]
|
|
661
|
+
labels: Optional[List[str]]
|
|
662
|
+
|
|
663
|
+
|
|
622
664
|
class VideoRectangleTag(ControlTag):
|
|
623
665
|
""" """
|
|
624
|
-
|
|
666
|
+
_label_attr_name: str = "labels"
|
|
625
667
|
_value_class: Type[VideoRectangleValue] = VideoRectangleValue
|
|
626
|
-
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
class NumberValue(BaseModel):
|
|
671
|
+
number: int = Field(..., ge=0)
|
|
672
|
+
|
|
627
673
|
|
|
628
674
|
class NumberTag(ControlTag):
|
|
629
675
|
""" """
|
|
676
|
+
_value_class: Type[NumberValue] = NumberValue
|
|
677
|
+
|
|
630
678
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
# TODO implement
|
|
634
|
-
return True
|
|
635
|
-
|
|
636
|
-
def label(self, *args, **kwargs):
|
|
637
|
-
""" """
|
|
638
|
-
|
|
679
|
+
class DateTimeValue(BaseModel):
|
|
680
|
+
datetime: str
|
|
639
681
|
|
|
682
|
+
|
|
640
683
|
class DateTimeTag(ControlTag):
|
|
641
684
|
""" """
|
|
642
|
-
|
|
643
|
-
def validate_value(self, value) -> bool:
|
|
644
|
-
""" """
|
|
645
|
-
# TODO implement
|
|
646
|
-
return True
|
|
647
|
-
|
|
648
|
-
def label(self, *args, **kwargs):
|
|
649
|
-
""" """
|
|
685
|
+
_value_class: Type[DateTimeValue] = DateTimeValue
|
|
650
686
|
|
|
651
687
|
|
|
652
688
|
class HyperTextLabelsValue(SpanSelectionOffsets):
|
|
@@ -669,8 +705,10 @@ class PairwiseTag(ControlTag):
|
|
|
669
705
|
|
|
670
706
|
_value_class: Type[PairwiseValue] = PairwiseValue
|
|
671
707
|
|
|
672
|
-
def label(self,
|
|
708
|
+
def label(self, side):
|
|
673
709
|
""" """
|
|
710
|
+
value = PairwiseValue(selected=side)
|
|
711
|
+
return Region(from_tag=self, to_tag=self, value=value)
|
|
674
712
|
|
|
675
713
|
|
|
676
714
|
class ParagraphLabelsValue(SpanSelectionOffsets):
|
|
@@ -683,46 +721,46 @@ class ParagraphLabelsTag(ControlTag):
|
|
|
683
721
|
_label_attr_name: str = "paragraphlabels"
|
|
684
722
|
_value_class: Type[ParagraphLabelsValue] = ParagraphLabelsValue
|
|
685
723
|
|
|
686
|
-
def label(self, *args, **kwargs):
|
|
724
|
+
def label(self, utterance=None, *args, **kwargs):
|
|
687
725
|
""" """
|
|
726
|
+
if isinstance(utterance, int):
|
|
727
|
+
kwargs["start"] = utterance
|
|
728
|
+
kwargs["end"] = utterance
|
|
729
|
+
|
|
730
|
+
return super().label(*args, **kwargs)
|
|
731
|
+
|
|
688
732
|
|
|
733
|
+
class RankerValue(BaseModel):
|
|
734
|
+
rank: List[str]
|
|
689
735
|
|
|
736
|
+
|
|
690
737
|
class RankerTag(ControlTag):
|
|
691
738
|
""" """
|
|
692
|
-
|
|
693
|
-
def validate_value(self, value) -> bool:
|
|
694
|
-
""" """
|
|
695
|
-
# TODO
|
|
696
|
-
return True
|
|
697
|
-
|
|
698
|
-
def label(self, *args, **kwargs):
|
|
699
|
-
""" """
|
|
739
|
+
_value_class: Type[RankerValue] = RankerValue
|
|
700
740
|
|
|
701
741
|
|
|
702
742
|
class RatingValue(BaseModel):
|
|
703
|
-
rating: int
|
|
743
|
+
rating: int = Field(..., ge=0)
|
|
704
744
|
|
|
705
745
|
|
|
706
746
|
class RatingTag(ControlTag):
|
|
707
747
|
""" """
|
|
708
|
-
|
|
709
748
|
_value_class: Type[RatingValue] = RatingValue
|
|
710
749
|
|
|
711
|
-
def label(self, *args, **kwargs):
|
|
712
|
-
""" """
|
|
713
|
-
|
|
714
750
|
|
|
715
751
|
class RelationsTag(ControlTag):
|
|
716
752
|
""" """
|
|
717
|
-
|
|
718
|
-
def validate_value(self, value) -> bool:
|
|
753
|
+
def validate_value(self, ) -> bool:
|
|
719
754
|
""" """
|
|
720
|
-
|
|
721
|
-
|
|
755
|
+
raise NotImplemented("""Should not be called directly, instead
|
|
756
|
+
use validate_relation() method found in LabelInterface class""")
|
|
722
757
|
|
|
723
758
|
def label(self, *args, **kwargs):
|
|
724
759
|
""" """
|
|
725
|
-
|
|
760
|
+
raise NotImplemented("""
|
|
761
|
+
Relations work on regions instead of Object tags
|
|
762
|
+
use Regions add_relation() method""")
|
|
763
|
+
|
|
726
764
|
|
|
727
765
|
class TaxonomyValue(BaseModel):
|
|
728
766
|
taxonomy: List[List[str]]
|