label-studio-sdk 1.0.5__py3-none-any.whl → 1.0.8__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.
Potentially problematic release.
This version of label-studio-sdk might be problematic. Click here for more details.
- label_studio_sdk/__init__.py +76 -0
- label_studio_sdk/_extensions/eval/categorical.py +83 -0
- label_studio_sdk/_extensions/label_studio_tools/core/label_config.py +13 -4
- label_studio_sdk/_extensions/label_studio_tools/core/utils/io.py +35 -17
- label_studio_sdk/_extensions/label_studio_tools/core/utils/json_schema.py +86 -0
- label_studio_sdk/_legacy/schema/label_config_schema.json +42 -11
- label_studio_sdk/annotations/__init__.py +3 -0
- label_studio_sdk/annotations/client.py +109 -0
- label_studio_sdk/annotations/types/__init__.py +5 -0
- label_studio_sdk/annotations/types/annotations_create_bulk_response_item.py +29 -0
- label_studio_sdk/base_client.py +9 -0
- label_studio_sdk/comments/__init__.py +2 -0
- label_studio_sdk/comments/client.py +512 -0
- label_studio_sdk/converter/converter.py +11 -4
- label_studio_sdk/converter/imports/coco.py +14 -13
- label_studio_sdk/converter/utils.py +72 -3
- label_studio_sdk/core/client_wrapper.py +1 -1
- label_studio_sdk/files/client.py +26 -16
- label_studio_sdk/label_interface/control_tags.py +205 -10
- label_studio_sdk/label_interface/interface.py +117 -10
- label_studio_sdk/label_interface/region.py +1 -10
- label_studio_sdk/model_providers/__init__.py +2 -0
- label_studio_sdk/model_providers/client.py +708 -0
- label_studio_sdk/projects/client.py +32 -16
- label_studio_sdk/projects/exports/client.py +133 -40
- label_studio_sdk/prompts/__init__.py +21 -0
- label_studio_sdk/prompts/client.py +862 -0
- label_studio_sdk/prompts/indicators/__init__.py +2 -0
- label_studio_sdk/prompts/indicators/client.py +194 -0
- label_studio_sdk/prompts/runs/__init__.py +5 -0
- label_studio_sdk/prompts/runs/client.py +354 -0
- label_studio_sdk/prompts/runs/types/__init__.py +5 -0
- label_studio_sdk/prompts/runs/types/runs_list_request_project_subset.py +5 -0
- label_studio_sdk/prompts/types/__init__.py +15 -0
- label_studio_sdk/prompts/types/prompts_batch_failed_predictions_request_failed_predictions_item.py +42 -0
- label_studio_sdk/prompts/types/prompts_batch_failed_predictions_response.py +29 -0
- label_studio_sdk/prompts/types/prompts_batch_predictions_request_results_item.py +62 -0
- label_studio_sdk/prompts/types/prompts_batch_predictions_response.py +29 -0
- label_studio_sdk/prompts/versions/__init__.py +2 -0
- label_studio_sdk/prompts/versions/client.py +1046 -0
- label_studio_sdk/types/__init__.py +58 -0
- label_studio_sdk/types/comment.py +39 -0
- label_studio_sdk/types/comment_created_by.py +5 -0
- label_studio_sdk/types/inference_run.py +43 -0
- label_studio_sdk/types/inference_run_cost_estimate.py +57 -0
- label_studio_sdk/types/inference_run_created_by.py +5 -0
- label_studio_sdk/types/inference_run_organization.py +5 -0
- label_studio_sdk/types/inference_run_project_subset.py +5 -0
- label_studio_sdk/types/inference_run_status.py +7 -0
- label_studio_sdk/types/key_indicator_value.py +30 -0
- label_studio_sdk/types/key_indicators.py +7 -0
- label_studio_sdk/types/key_indicators_item.py +51 -0
- label_studio_sdk/types/key_indicators_item_additional_kpis_item.py +37 -0
- label_studio_sdk/types/key_indicators_item_extra_kpis_item.py +37 -0
- label_studio_sdk/types/model_provider_connection.py +71 -0
- label_studio_sdk/types/model_provider_connection_budget_reset_period.py +5 -0
- label_studio_sdk/types/model_provider_connection_created_by.py +5 -0
- label_studio_sdk/types/model_provider_connection_organization.py +5 -0
- label_studio_sdk/types/model_provider_connection_provider.py +5 -0
- label_studio_sdk/types/model_provider_connection_scope.py +5 -0
- label_studio_sdk/types/prompt.py +79 -0
- label_studio_sdk/types/prompt_created_by.py +5 -0
- label_studio_sdk/types/prompt_organization.py +5 -0
- label_studio_sdk/types/prompt_version.py +41 -0
- label_studio_sdk/types/prompt_version_created_by.py +5 -0
- label_studio_sdk/types/prompt_version_organization.py +5 -0
- label_studio_sdk/types/prompt_version_provider.py +5 -0
- label_studio_sdk/types/refined_prompt_response.py +64 -0
- label_studio_sdk/types/refined_prompt_response_refinement_status.py +7 -0
- label_studio_sdk/types/task.py +3 -2
- label_studio_sdk/types/task_comment_authors_item.py +5 -0
- label_studio_sdk/webhooks/client.py +245 -36
- label_studio_sdk/workspaces/client.py +20 -20
- label_studio_sdk-1.0.8.dist-info/LICENSE +201 -0
- {label_studio_sdk-1.0.5.dist-info → label_studio_sdk-1.0.8.dist-info}/METADATA +19 -3
- {label_studio_sdk-1.0.5.dist-info → label_studio_sdk-1.0.8.dist-info}/RECORD +77 -24
- {label_studio_sdk-1.0.5.dist-info → label_studio_sdk-1.0.8.dist-info}/WHEEL +1 -1
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
from json.decoder import JSONDecodeError
|
|
5
|
+
|
|
6
|
+
from ..core.api_error import ApiError
|
|
7
|
+
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
|
|
8
|
+
from ..core.jsonable_encoder import jsonable_encoder
|
|
9
|
+
from ..core.pydantic_utilities import pydantic_v1
|
|
10
|
+
from ..core.request_options import RequestOptions
|
|
11
|
+
from ..types.comment import Comment
|
|
12
|
+
|
|
13
|
+
# this is used as the default value for optional parameters
|
|
14
|
+
OMIT = typing.cast(typing.Any, ...)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CommentsClient:
|
|
18
|
+
def __init__(self, *, client_wrapper: SyncClientWrapper):
|
|
19
|
+
self._client_wrapper = client_wrapper
|
|
20
|
+
|
|
21
|
+
def list(
|
|
22
|
+
self,
|
|
23
|
+
*,
|
|
24
|
+
project: typing.Optional[int] = None,
|
|
25
|
+
expand_created_by: typing.Optional[bool] = None,
|
|
26
|
+
annotation: typing.Optional[int] = None,
|
|
27
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
28
|
+
) -> typing.List[Comment]:
|
|
29
|
+
"""
|
|
30
|
+
Get a list of comments for a specific project.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
project : typing.Optional[int]
|
|
35
|
+
Project ID
|
|
36
|
+
|
|
37
|
+
expand_created_by : typing.Optional[bool]
|
|
38
|
+
Expand the created_by field with object instead of ID
|
|
39
|
+
|
|
40
|
+
annotation : typing.Optional[int]
|
|
41
|
+
Annotation ID
|
|
42
|
+
|
|
43
|
+
request_options : typing.Optional[RequestOptions]
|
|
44
|
+
Request-specific configuration.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
typing.List[Comment]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
Examples
|
|
52
|
+
--------
|
|
53
|
+
from label_studio_sdk.client import LabelStudio
|
|
54
|
+
|
|
55
|
+
client = LabelStudio(
|
|
56
|
+
api_key="YOUR_API_KEY",
|
|
57
|
+
)
|
|
58
|
+
client.comments.list()
|
|
59
|
+
"""
|
|
60
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
61
|
+
"api/comments/",
|
|
62
|
+
method="GET",
|
|
63
|
+
params={"project": project, "expand_created_by": expand_created_by, "annotation": annotation},
|
|
64
|
+
request_options=request_options,
|
|
65
|
+
)
|
|
66
|
+
try:
|
|
67
|
+
if 200 <= _response.status_code < 300:
|
|
68
|
+
return pydantic_v1.parse_obj_as(typing.List[Comment], _response.json()) # type: ignore
|
|
69
|
+
_response_json = _response.json()
|
|
70
|
+
except JSONDecodeError:
|
|
71
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
72
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
73
|
+
|
|
74
|
+
def create(
|
|
75
|
+
self,
|
|
76
|
+
*,
|
|
77
|
+
annotation: typing.Optional[int] = OMIT,
|
|
78
|
+
project: typing.Optional[int] = OMIT,
|
|
79
|
+
text: typing.Optional[str] = OMIT,
|
|
80
|
+
is_resolved: typing.Optional[bool] = OMIT,
|
|
81
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
82
|
+
) -> Comment:
|
|
83
|
+
"""
|
|
84
|
+
Create a new comment.
|
|
85
|
+
|
|
86
|
+
Parameters
|
|
87
|
+
----------
|
|
88
|
+
annotation : typing.Optional[int]
|
|
89
|
+
|
|
90
|
+
project : typing.Optional[int]
|
|
91
|
+
|
|
92
|
+
text : typing.Optional[str]
|
|
93
|
+
|
|
94
|
+
is_resolved : typing.Optional[bool]
|
|
95
|
+
|
|
96
|
+
request_options : typing.Optional[RequestOptions]
|
|
97
|
+
Request-specific configuration.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
Comment
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
Examples
|
|
105
|
+
--------
|
|
106
|
+
from label_studio_sdk.client import LabelStudio
|
|
107
|
+
|
|
108
|
+
client = LabelStudio(
|
|
109
|
+
api_key="YOUR_API_KEY",
|
|
110
|
+
)
|
|
111
|
+
client.comments.create()
|
|
112
|
+
"""
|
|
113
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
114
|
+
"api/comments/",
|
|
115
|
+
method="POST",
|
|
116
|
+
json={"annotation": annotation, "project": project, "text": text, "is_resolved": is_resolved},
|
|
117
|
+
request_options=request_options,
|
|
118
|
+
omit=OMIT,
|
|
119
|
+
)
|
|
120
|
+
try:
|
|
121
|
+
if 200 <= _response.status_code < 300:
|
|
122
|
+
return pydantic_v1.parse_obj_as(Comment, _response.json()) # type: ignore
|
|
123
|
+
_response_json = _response.json()
|
|
124
|
+
except JSONDecodeError:
|
|
125
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
126
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
127
|
+
|
|
128
|
+
def get(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Comment:
|
|
129
|
+
"""
|
|
130
|
+
Get a specific comment.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
id : int
|
|
135
|
+
Comment ID
|
|
136
|
+
|
|
137
|
+
request_options : typing.Optional[RequestOptions]
|
|
138
|
+
Request-specific configuration.
|
|
139
|
+
|
|
140
|
+
Returns
|
|
141
|
+
-------
|
|
142
|
+
Comment
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
Examples
|
|
146
|
+
--------
|
|
147
|
+
from label_studio_sdk.client import LabelStudio
|
|
148
|
+
|
|
149
|
+
client = LabelStudio(
|
|
150
|
+
api_key="YOUR_API_KEY",
|
|
151
|
+
)
|
|
152
|
+
client.comments.get(
|
|
153
|
+
id=1,
|
|
154
|
+
)
|
|
155
|
+
"""
|
|
156
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
157
|
+
f"api/comments/{jsonable_encoder(id)}", method="GET", request_options=request_options
|
|
158
|
+
)
|
|
159
|
+
try:
|
|
160
|
+
if 200 <= _response.status_code < 300:
|
|
161
|
+
return pydantic_v1.parse_obj_as(Comment, _response.json()) # type: ignore
|
|
162
|
+
_response_json = _response.json()
|
|
163
|
+
except JSONDecodeError:
|
|
164
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
165
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
166
|
+
|
|
167
|
+
def delete(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> None:
|
|
168
|
+
"""
|
|
169
|
+
Delete a specific comment.
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
id : int
|
|
174
|
+
Comment ID
|
|
175
|
+
|
|
176
|
+
request_options : typing.Optional[RequestOptions]
|
|
177
|
+
Request-specific configuration.
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
None
|
|
182
|
+
|
|
183
|
+
Examples
|
|
184
|
+
--------
|
|
185
|
+
from label_studio_sdk.client import LabelStudio
|
|
186
|
+
|
|
187
|
+
client = LabelStudio(
|
|
188
|
+
api_key="YOUR_API_KEY",
|
|
189
|
+
)
|
|
190
|
+
client.comments.delete(
|
|
191
|
+
id=1,
|
|
192
|
+
)
|
|
193
|
+
"""
|
|
194
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
195
|
+
f"api/comments/{jsonable_encoder(id)}", method="DELETE", request_options=request_options
|
|
196
|
+
)
|
|
197
|
+
try:
|
|
198
|
+
if 200 <= _response.status_code < 300:
|
|
199
|
+
return
|
|
200
|
+
_response_json = _response.json()
|
|
201
|
+
except JSONDecodeError:
|
|
202
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
203
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
204
|
+
|
|
205
|
+
def update(
|
|
206
|
+
self,
|
|
207
|
+
id: int,
|
|
208
|
+
*,
|
|
209
|
+
annotation: typing.Optional[int] = OMIT,
|
|
210
|
+
project: typing.Optional[int] = OMIT,
|
|
211
|
+
text: typing.Optional[str] = OMIT,
|
|
212
|
+
is_resolved: typing.Optional[bool] = OMIT,
|
|
213
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
214
|
+
) -> Comment:
|
|
215
|
+
"""
|
|
216
|
+
Update a specific comment.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
id : int
|
|
221
|
+
Comment ID
|
|
222
|
+
|
|
223
|
+
annotation : typing.Optional[int]
|
|
224
|
+
|
|
225
|
+
project : typing.Optional[int]
|
|
226
|
+
|
|
227
|
+
text : typing.Optional[str]
|
|
228
|
+
|
|
229
|
+
is_resolved : typing.Optional[bool]
|
|
230
|
+
|
|
231
|
+
request_options : typing.Optional[RequestOptions]
|
|
232
|
+
Request-specific configuration.
|
|
233
|
+
|
|
234
|
+
Returns
|
|
235
|
+
-------
|
|
236
|
+
Comment
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
Examples
|
|
240
|
+
--------
|
|
241
|
+
from label_studio_sdk.client import LabelStudio
|
|
242
|
+
|
|
243
|
+
client = LabelStudio(
|
|
244
|
+
api_key="YOUR_API_KEY",
|
|
245
|
+
)
|
|
246
|
+
client.comments.update(
|
|
247
|
+
id=1,
|
|
248
|
+
)
|
|
249
|
+
"""
|
|
250
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
251
|
+
f"api/comments/{jsonable_encoder(id)}",
|
|
252
|
+
method="PATCH",
|
|
253
|
+
json={"annotation": annotation, "project": project, "text": text, "is_resolved": is_resolved},
|
|
254
|
+
request_options=request_options,
|
|
255
|
+
omit=OMIT,
|
|
256
|
+
)
|
|
257
|
+
try:
|
|
258
|
+
if 200 <= _response.status_code < 300:
|
|
259
|
+
return pydantic_v1.parse_obj_as(Comment, _response.json()) # type: ignore
|
|
260
|
+
_response_json = _response.json()
|
|
261
|
+
except JSONDecodeError:
|
|
262
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
263
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
class AsyncCommentsClient:
|
|
267
|
+
def __init__(self, *, client_wrapper: AsyncClientWrapper):
|
|
268
|
+
self._client_wrapper = client_wrapper
|
|
269
|
+
|
|
270
|
+
async def list(
|
|
271
|
+
self,
|
|
272
|
+
*,
|
|
273
|
+
project: typing.Optional[int] = None,
|
|
274
|
+
expand_created_by: typing.Optional[bool] = None,
|
|
275
|
+
annotation: typing.Optional[int] = None,
|
|
276
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
277
|
+
) -> typing.List[Comment]:
|
|
278
|
+
"""
|
|
279
|
+
Get a list of comments for a specific project.
|
|
280
|
+
|
|
281
|
+
Parameters
|
|
282
|
+
----------
|
|
283
|
+
project : typing.Optional[int]
|
|
284
|
+
Project ID
|
|
285
|
+
|
|
286
|
+
expand_created_by : typing.Optional[bool]
|
|
287
|
+
Expand the created_by field with object instead of ID
|
|
288
|
+
|
|
289
|
+
annotation : typing.Optional[int]
|
|
290
|
+
Annotation ID
|
|
291
|
+
|
|
292
|
+
request_options : typing.Optional[RequestOptions]
|
|
293
|
+
Request-specific configuration.
|
|
294
|
+
|
|
295
|
+
Returns
|
|
296
|
+
-------
|
|
297
|
+
typing.List[Comment]
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
Examples
|
|
301
|
+
--------
|
|
302
|
+
from label_studio_sdk.client import AsyncLabelStudio
|
|
303
|
+
|
|
304
|
+
client = AsyncLabelStudio(
|
|
305
|
+
api_key="YOUR_API_KEY",
|
|
306
|
+
)
|
|
307
|
+
await client.comments.list()
|
|
308
|
+
"""
|
|
309
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
310
|
+
"api/comments/",
|
|
311
|
+
method="GET",
|
|
312
|
+
params={"project": project, "expand_created_by": expand_created_by, "annotation": annotation},
|
|
313
|
+
request_options=request_options,
|
|
314
|
+
)
|
|
315
|
+
try:
|
|
316
|
+
if 200 <= _response.status_code < 300:
|
|
317
|
+
return pydantic_v1.parse_obj_as(typing.List[Comment], _response.json()) # type: ignore
|
|
318
|
+
_response_json = _response.json()
|
|
319
|
+
except JSONDecodeError:
|
|
320
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
321
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
322
|
+
|
|
323
|
+
async def create(
|
|
324
|
+
self,
|
|
325
|
+
*,
|
|
326
|
+
annotation: typing.Optional[int] = OMIT,
|
|
327
|
+
project: typing.Optional[int] = OMIT,
|
|
328
|
+
text: typing.Optional[str] = OMIT,
|
|
329
|
+
is_resolved: typing.Optional[bool] = OMIT,
|
|
330
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
331
|
+
) -> Comment:
|
|
332
|
+
"""
|
|
333
|
+
Create a new comment.
|
|
334
|
+
|
|
335
|
+
Parameters
|
|
336
|
+
----------
|
|
337
|
+
annotation : typing.Optional[int]
|
|
338
|
+
|
|
339
|
+
project : typing.Optional[int]
|
|
340
|
+
|
|
341
|
+
text : typing.Optional[str]
|
|
342
|
+
|
|
343
|
+
is_resolved : typing.Optional[bool]
|
|
344
|
+
|
|
345
|
+
request_options : typing.Optional[RequestOptions]
|
|
346
|
+
Request-specific configuration.
|
|
347
|
+
|
|
348
|
+
Returns
|
|
349
|
+
-------
|
|
350
|
+
Comment
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
Examples
|
|
354
|
+
--------
|
|
355
|
+
from label_studio_sdk.client import AsyncLabelStudio
|
|
356
|
+
|
|
357
|
+
client = AsyncLabelStudio(
|
|
358
|
+
api_key="YOUR_API_KEY",
|
|
359
|
+
)
|
|
360
|
+
await client.comments.create()
|
|
361
|
+
"""
|
|
362
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
363
|
+
"api/comments/",
|
|
364
|
+
method="POST",
|
|
365
|
+
json={"annotation": annotation, "project": project, "text": text, "is_resolved": is_resolved},
|
|
366
|
+
request_options=request_options,
|
|
367
|
+
omit=OMIT,
|
|
368
|
+
)
|
|
369
|
+
try:
|
|
370
|
+
if 200 <= _response.status_code < 300:
|
|
371
|
+
return pydantic_v1.parse_obj_as(Comment, _response.json()) # type: ignore
|
|
372
|
+
_response_json = _response.json()
|
|
373
|
+
except JSONDecodeError:
|
|
374
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
375
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
376
|
+
|
|
377
|
+
async def get(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Comment:
|
|
378
|
+
"""
|
|
379
|
+
Get a specific comment.
|
|
380
|
+
|
|
381
|
+
Parameters
|
|
382
|
+
----------
|
|
383
|
+
id : int
|
|
384
|
+
Comment ID
|
|
385
|
+
|
|
386
|
+
request_options : typing.Optional[RequestOptions]
|
|
387
|
+
Request-specific configuration.
|
|
388
|
+
|
|
389
|
+
Returns
|
|
390
|
+
-------
|
|
391
|
+
Comment
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
Examples
|
|
395
|
+
--------
|
|
396
|
+
from label_studio_sdk.client import AsyncLabelStudio
|
|
397
|
+
|
|
398
|
+
client = AsyncLabelStudio(
|
|
399
|
+
api_key="YOUR_API_KEY",
|
|
400
|
+
)
|
|
401
|
+
await client.comments.get(
|
|
402
|
+
id=1,
|
|
403
|
+
)
|
|
404
|
+
"""
|
|
405
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
406
|
+
f"api/comments/{jsonable_encoder(id)}", method="GET", request_options=request_options
|
|
407
|
+
)
|
|
408
|
+
try:
|
|
409
|
+
if 200 <= _response.status_code < 300:
|
|
410
|
+
return pydantic_v1.parse_obj_as(Comment, _response.json()) # type: ignore
|
|
411
|
+
_response_json = _response.json()
|
|
412
|
+
except JSONDecodeError:
|
|
413
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
414
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
415
|
+
|
|
416
|
+
async def delete(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> None:
|
|
417
|
+
"""
|
|
418
|
+
Delete a specific comment.
|
|
419
|
+
|
|
420
|
+
Parameters
|
|
421
|
+
----------
|
|
422
|
+
id : int
|
|
423
|
+
Comment ID
|
|
424
|
+
|
|
425
|
+
request_options : typing.Optional[RequestOptions]
|
|
426
|
+
Request-specific configuration.
|
|
427
|
+
|
|
428
|
+
Returns
|
|
429
|
+
-------
|
|
430
|
+
None
|
|
431
|
+
|
|
432
|
+
Examples
|
|
433
|
+
--------
|
|
434
|
+
from label_studio_sdk.client import AsyncLabelStudio
|
|
435
|
+
|
|
436
|
+
client = AsyncLabelStudio(
|
|
437
|
+
api_key="YOUR_API_KEY",
|
|
438
|
+
)
|
|
439
|
+
await client.comments.delete(
|
|
440
|
+
id=1,
|
|
441
|
+
)
|
|
442
|
+
"""
|
|
443
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
444
|
+
f"api/comments/{jsonable_encoder(id)}", method="DELETE", request_options=request_options
|
|
445
|
+
)
|
|
446
|
+
try:
|
|
447
|
+
if 200 <= _response.status_code < 300:
|
|
448
|
+
return
|
|
449
|
+
_response_json = _response.json()
|
|
450
|
+
except JSONDecodeError:
|
|
451
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
452
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
453
|
+
|
|
454
|
+
async def update(
|
|
455
|
+
self,
|
|
456
|
+
id: int,
|
|
457
|
+
*,
|
|
458
|
+
annotation: typing.Optional[int] = OMIT,
|
|
459
|
+
project: typing.Optional[int] = OMIT,
|
|
460
|
+
text: typing.Optional[str] = OMIT,
|
|
461
|
+
is_resolved: typing.Optional[bool] = OMIT,
|
|
462
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
463
|
+
) -> Comment:
|
|
464
|
+
"""
|
|
465
|
+
Update a specific comment.
|
|
466
|
+
|
|
467
|
+
Parameters
|
|
468
|
+
----------
|
|
469
|
+
id : int
|
|
470
|
+
Comment ID
|
|
471
|
+
|
|
472
|
+
annotation : typing.Optional[int]
|
|
473
|
+
|
|
474
|
+
project : typing.Optional[int]
|
|
475
|
+
|
|
476
|
+
text : typing.Optional[str]
|
|
477
|
+
|
|
478
|
+
is_resolved : typing.Optional[bool]
|
|
479
|
+
|
|
480
|
+
request_options : typing.Optional[RequestOptions]
|
|
481
|
+
Request-specific configuration.
|
|
482
|
+
|
|
483
|
+
Returns
|
|
484
|
+
-------
|
|
485
|
+
Comment
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
Examples
|
|
489
|
+
--------
|
|
490
|
+
from label_studio_sdk.client import AsyncLabelStudio
|
|
491
|
+
|
|
492
|
+
client = AsyncLabelStudio(
|
|
493
|
+
api_key="YOUR_API_KEY",
|
|
494
|
+
)
|
|
495
|
+
await client.comments.update(
|
|
496
|
+
id=1,
|
|
497
|
+
)
|
|
498
|
+
"""
|
|
499
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
500
|
+
f"api/comments/{jsonable_encoder(id)}",
|
|
501
|
+
method="PATCH",
|
|
502
|
+
json={"annotation": annotation, "project": project, "text": text, "is_resolved": is_resolved},
|
|
503
|
+
request_options=request_options,
|
|
504
|
+
omit=OMIT,
|
|
505
|
+
)
|
|
506
|
+
try:
|
|
507
|
+
if 200 <= _response.status_code < 300:
|
|
508
|
+
return pydantic_v1.parse_obj_as(Comment, _response.json()) # type: ignore
|
|
509
|
+
_response_json = _response.json()
|
|
510
|
+
except JSONDecodeError:
|
|
511
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
512
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
@@ -10,7 +10,6 @@ from copy import deepcopy
|
|
|
10
10
|
from datetime import datetime
|
|
11
11
|
from enum import Enum
|
|
12
12
|
from glob import glob
|
|
13
|
-
from operator import itemgetter
|
|
14
13
|
from shutil import copy2
|
|
15
14
|
from typing import Optional
|
|
16
15
|
|
|
@@ -282,12 +281,16 @@ class Converter(object):
|
|
|
282
281
|
for name, info in self._schema.items():
|
|
283
282
|
if output_tags is not None and name not in output_tags:
|
|
284
283
|
continue
|
|
285
|
-
|
|
284
|
+
for input_tag in info["inputs"]:
|
|
285
|
+
for value_key_name in ["value", "valueList"]:
|
|
286
|
+
if value_key_name in input_tag:
|
|
287
|
+
data_keys.add(input_tag[value_key_name])
|
|
286
288
|
output_tag_names.append(name)
|
|
287
289
|
|
|
288
290
|
return list(data_keys), output_tag_names
|
|
289
291
|
|
|
290
292
|
def _get_supported_formats(self):
|
|
293
|
+
is_mig = False
|
|
291
294
|
if len(self._data_keys) > 1:
|
|
292
295
|
return [
|
|
293
296
|
Format.JSON.name,
|
|
@@ -300,6 +303,8 @@ class Converter(object):
|
|
|
300
303
|
for info in self._schema.values():
|
|
301
304
|
output_tag_types.add(info["type"])
|
|
302
305
|
for input_tag in info["inputs"]:
|
|
306
|
+
if input_tag.get("valueList"):
|
|
307
|
+
is_mig = True
|
|
303
308
|
if input_tag["type"] == "Text" and input_tag.get("valueType") == "url":
|
|
304
309
|
logger.error('valueType="url" are not supported for text inputs')
|
|
305
310
|
continue
|
|
@@ -308,7 +313,7 @@ class Converter(object):
|
|
|
308
313
|
all_formats = [f.name for f in Format]
|
|
309
314
|
if not ("Text" in input_tag_types and "Labels" in output_tag_types):
|
|
310
315
|
all_formats.remove(Format.CONLL2003.name)
|
|
311
|
-
if not (
|
|
316
|
+
if is_mig or not (
|
|
312
317
|
"Image" in input_tag_types
|
|
313
318
|
and (
|
|
314
319
|
"RectangleLabels" in output_tag_types
|
|
@@ -317,7 +322,7 @@ class Converter(object):
|
|
|
317
322
|
)
|
|
318
323
|
):
|
|
319
324
|
all_formats.remove(Format.VOC.name)
|
|
320
|
-
if not (
|
|
325
|
+
if is_mig or not (
|
|
321
326
|
"Image" in input_tag_types
|
|
322
327
|
and (
|
|
323
328
|
"RectangleLabels" in output_tag_types
|
|
@@ -346,6 +351,8 @@ class Converter(object):
|
|
|
346
351
|
and "TextArea" in output_tag_types
|
|
347
352
|
):
|
|
348
353
|
all_formats.remove(Format.ASR_MANIFEST.name)
|
|
354
|
+
if is_mig or ('Video' in input_tag_types and 'TimelineLabels' in output_tag_types):
|
|
355
|
+
all_formats.remove(Format.YOLO_OBB.name)
|
|
349
356
|
|
|
350
357
|
return all_formats
|
|
351
358
|
|
|
@@ -48,10 +48,9 @@ def create_bbox(annotation, categories, from_name, image_height, image_width, to
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
def create_segmentation(
|
|
51
|
-
|
|
51
|
+
category_id, segmentation, categories, from_name, image_height, image_width, to_name
|
|
52
52
|
):
|
|
53
|
-
label = categories[int(
|
|
54
|
-
segmentation = annotation["segmentation"][0]
|
|
53
|
+
label = categories[int(category_id)]
|
|
55
54
|
points = [list(x) for x in zip(*[iter(segmentation)] * 2)]
|
|
56
55
|
|
|
57
56
|
for i in range(len(points)):
|
|
@@ -216,15 +215,17 @@ def convert_coco_to_ls(
|
|
|
216
215
|
task[out_type][0]["result"].append(item)
|
|
217
216
|
|
|
218
217
|
if "segmentation" in annotation and len(annotation["segmentation"]):
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
218
|
+
for single_segmentation in annotation["segmentation"]:
|
|
219
|
+
item = create_segmentation(
|
|
220
|
+
annotation["category_id"],
|
|
221
|
+
single_segmentation,
|
|
222
|
+
categories,
|
|
223
|
+
segmentation_from_name,
|
|
224
|
+
image_height,
|
|
225
|
+
image_width,
|
|
226
|
+
to_name,
|
|
227
|
+
)
|
|
228
|
+
task[out_type][0]["result"].append(item)
|
|
228
229
|
|
|
229
230
|
if "keypoints" in annotation:
|
|
230
231
|
items = create_keypoints(
|
|
@@ -270,7 +271,7 @@ def add_parser(subparsers):
|
|
|
270
271
|
"--input",
|
|
271
272
|
dest="input",
|
|
272
273
|
required=True,
|
|
273
|
-
help="
|
|
274
|
+
help="input COCO json file",
|
|
274
275
|
action=ExpandFullPath,
|
|
275
276
|
)
|
|
276
277
|
coco.add_argument(
|