label-studio-sdk 1.0.2__py3-none-any.whl → 1.0.4__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 +20 -1
- label_studio_sdk/actions/client.py +8 -8
- label_studio_sdk/annotations/client.py +24 -24
- label_studio_sdk/base_client.py +3 -0
- label_studio_sdk/core/client_wrapper.py +1 -1
- label_studio_sdk/core/http_client.py +36 -8
- label_studio_sdk/core/request_options.py +2 -2
- label_studio_sdk/export_storage/__init__.py +2 -1
- label_studio_sdk/export_storage/azure/client.py +28 -28
- label_studio_sdk/export_storage/client.py +7 -4
- label_studio_sdk/export_storage/gcs/client.py +28 -28
- label_studio_sdk/export_storage/local/client.py +28 -28
- label_studio_sdk/export_storage/redis/client.py +28 -28
- label_studio_sdk/export_storage/s3/client.py +28 -28
- label_studio_sdk/export_storage/s3s/__init__.py +2 -0
- label_studio_sdk/export_storage/s3s/client.py +836 -0
- label_studio_sdk/files/client.py +24 -24
- label_studio_sdk/import_storage/__init__.py +2 -1
- label_studio_sdk/import_storage/azure/client.py +28 -28
- label_studio_sdk/import_storage/client.py +7 -4
- label_studio_sdk/import_storage/gcs/client.py +28 -28
- label_studio_sdk/import_storage/local/client.py +28 -28
- label_studio_sdk/import_storage/redis/client.py +28 -28
- label_studio_sdk/import_storage/s3/client.py +28 -28
- label_studio_sdk/import_storage/s3s/__init__.py +2 -0
- label_studio_sdk/import_storage/s3s/client.py +1054 -0
- label_studio_sdk/label_interface/base.py +2 -2
- label_studio_sdk/label_interface/control_tags.py +32 -18
- label_studio_sdk/label_interface/create.py +241 -0
- label_studio_sdk/label_interface/interface.py +68 -0
- label_studio_sdk/label_interface/object_tags.py +26 -10
- label_studio_sdk/label_interface/objects.py +5 -5
- label_studio_sdk/ml/client.py +36 -36
- label_studio_sdk/predictions/client.py +24 -24
- label_studio_sdk/projects/__init__.py +8 -2
- label_studio_sdk/projects/client.py +232 -69
- label_studio_sdk/projects/client_ext.py +16 -1
- label_studio_sdk/projects/exports/client.py +38 -38
- label_studio_sdk/projects/types/__init__.py +2 -1
- label_studio_sdk/projects/types/projects_update_response.py +96 -0
- label_studio_sdk/tasks/client.py +70 -60
- label_studio_sdk/tasks/client_ext.py +4 -0
- label_studio_sdk/types/__init__.py +16 -0
- label_studio_sdk/types/base_task.py +4 -2
- label_studio_sdk/types/base_task_file_upload.py +5 -0
- label_studio_sdk/types/base_task_updated_by.py +5 -0
- label_studio_sdk/types/data_manager_task_serializer.py +3 -2
- label_studio_sdk/types/data_manager_task_serializer_annotators_item.py +5 -0
- label_studio_sdk/types/s3s_export_storage.py +80 -0
- label_studio_sdk/types/s3s_import_storage.py +129 -0
- label_studio_sdk/types/s3s_import_storage_status.py +7 -0
- label_studio_sdk/types/task.py +3 -2
- label_studio_sdk/types/task_annotators_item.py +5 -0
- label_studio_sdk/types/workspace.py +77 -0
- label_studio_sdk/users/client.py +32 -32
- label_studio_sdk/views/client.py +24 -24
- label_studio_sdk/webhooks/client.py +24 -24
- label_studio_sdk/workspaces/__init__.py +6 -0
- label_studio_sdk/workspaces/client.py +569 -0
- label_studio_sdk/workspaces/members/__init__.py +5 -0
- label_studio_sdk/workspaces/members/client.py +297 -0
- label_studio_sdk/workspaces/members/types/__init__.py +6 -0
- label_studio_sdk/workspaces/members/types/members_create_response.py +32 -0
- label_studio_sdk/workspaces/members/types/members_list_response_item.py +32 -0
- {label_studio_sdk-1.0.2.dist-info → label_studio_sdk-1.0.4.dist-info}/METADATA +11 -12
- {label_studio_sdk-1.0.2.dist-info → label_studio_sdk-1.0.4.dist-info}/RECORD +67 -46
- {label_studio_sdk-1.0.2.dist-info → label_studio_sdk-1.0.4.dist-info}/WHEEL +0 -0
|
@@ -16,6 +16,7 @@ from .exports.client import AsyncExportsClient, ExportsClient
|
|
|
16
16
|
from .types.projects_create_response import ProjectsCreateResponse
|
|
17
17
|
from .types.projects_import_tasks_response import ProjectsImportTasksResponse
|
|
18
18
|
from .types.projects_list_response import ProjectsListResponse
|
|
19
|
+
from .types.projects_update_response import ProjectsUpdateResponse
|
|
19
20
|
|
|
20
21
|
# this is used as the default value for optional parameters
|
|
21
22
|
OMIT = typing.cast(typing.Any, ...)
|
|
@@ -80,7 +81,12 @@ class ProjectsClient:
|
|
|
80
81
|
client = LabelStudio(
|
|
81
82
|
api_key="YOUR_API_KEY",
|
|
82
83
|
)
|
|
83
|
-
client.projects.list()
|
|
84
|
+
response = client.projects.list()
|
|
85
|
+
for item in response:
|
|
86
|
+
yield item
|
|
87
|
+
# alternatively, you can paginate page-by-page
|
|
88
|
+
for page in response.iter_pages():
|
|
89
|
+
yield page
|
|
84
90
|
"""
|
|
85
91
|
page = page or 1
|
|
86
92
|
_response = self._client_wrapper.httpx_client.request(
|
|
@@ -89,20 +95,20 @@ class ProjectsClient:
|
|
|
89
95
|
params={"ordering": ordering, "ids": ids, "title": title, "page": page, "page_size": page_size},
|
|
90
96
|
request_options=request_options,
|
|
91
97
|
)
|
|
92
|
-
if 200 <= _response.status_code < 300:
|
|
93
|
-
_parsed_response = pydantic_v1.parse_obj_as(ProjectsListResponse, _response.json()) # type: ignore
|
|
94
|
-
_has_next = True
|
|
95
|
-
_get_next = lambda: self.list(
|
|
96
|
-
ordering=ordering,
|
|
97
|
-
ids=ids,
|
|
98
|
-
title=title,
|
|
99
|
-
page=page + 1,
|
|
100
|
-
page_size=page_size,
|
|
101
|
-
request_options=request_options,
|
|
102
|
-
)
|
|
103
|
-
_items = _parsed_response.results
|
|
104
|
-
return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
|
|
105
98
|
try:
|
|
99
|
+
if 200 <= _response.status_code < 300:
|
|
100
|
+
_parsed_response = pydantic_v1.parse_obj_as(ProjectsListResponse, _response.json()) # type: ignore
|
|
101
|
+
_has_next = True
|
|
102
|
+
_get_next = lambda: self.list(
|
|
103
|
+
ordering=ordering,
|
|
104
|
+
ids=ids,
|
|
105
|
+
title=title,
|
|
106
|
+
page=page + 1,
|
|
107
|
+
page_size=page_size,
|
|
108
|
+
request_options=request_options,
|
|
109
|
+
)
|
|
110
|
+
_items = _parsed_response.results
|
|
111
|
+
return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
|
|
106
112
|
_response_json = _response.json()
|
|
107
113
|
except JSONDecodeError:
|
|
108
114
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -124,6 +130,7 @@ class ProjectsClient:
|
|
|
124
130
|
maximum_annotations: typing.Optional[int] = OMIT,
|
|
125
131
|
color: typing.Optional[str] = OMIT,
|
|
126
132
|
control_weights: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
|
|
133
|
+
workspace: typing.Optional[int] = OMIT,
|
|
127
134
|
request_options: typing.Optional[RequestOptions] = None,
|
|
128
135
|
) -> ProjectsCreateResponse:
|
|
129
136
|
"""
|
|
@@ -178,6 +185,9 @@ class ProjectsClient:
|
|
|
178
185
|
control_weights : typing.Optional[typing.Dict[str, typing.Any]]
|
|
179
186
|
Dict of weights for each control tag in metric calculation. Each control tag (e.g. label or choice) will have its own key in control weight dict with weight for each label and overall weight. For example, if a bounding box annotation with a control tag named my_bbox should be included with 0.33 weight in agreement calculation, and the first label Car should be twice as important as Airplane, then you need to specify: {'my_bbox': {'type': 'RectangleLabels', 'labels': {'Car': 1.0, 'Airplane': 0.5}, 'overall': 0.33}
|
|
180
187
|
|
|
188
|
+
workspace : typing.Optional[int]
|
|
189
|
+
Workspace ID
|
|
190
|
+
|
|
181
191
|
request_options : typing.Optional[RequestOptions]
|
|
182
192
|
Request-specific configuration.
|
|
183
193
|
|
|
@@ -212,13 +222,14 @@ class ProjectsClient:
|
|
|
212
222
|
"maximum_annotations": maximum_annotations,
|
|
213
223
|
"color": color,
|
|
214
224
|
"control_weights": control_weights,
|
|
225
|
+
"workspace": workspace,
|
|
215
226
|
},
|
|
216
227
|
request_options=request_options,
|
|
217
228
|
omit=OMIT,
|
|
218
229
|
)
|
|
219
|
-
if 200 <= _response.status_code < 300:
|
|
220
|
-
return pydantic_v1.parse_obj_as(ProjectsCreateResponse, _response.json()) # type: ignore
|
|
221
230
|
try:
|
|
231
|
+
if 200 <= _response.status_code < 300:
|
|
232
|
+
return pydantic_v1.parse_obj_as(ProjectsCreateResponse, _response.json()) # type: ignore
|
|
222
233
|
_response_json = _response.json()
|
|
223
234
|
except JSONDecodeError:
|
|
224
235
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -255,9 +266,9 @@ class ProjectsClient:
|
|
|
255
266
|
_response = self._client_wrapper.httpx_client.request(
|
|
256
267
|
f"api/projects/{jsonable_encoder(id)}/", method="GET", request_options=request_options
|
|
257
268
|
)
|
|
258
|
-
if 200 <= _response.status_code < 300:
|
|
259
|
-
return pydantic_v1.parse_obj_as(Project, _response.json()) # type: ignore
|
|
260
269
|
try:
|
|
270
|
+
if 200 <= _response.status_code < 300:
|
|
271
|
+
return pydantic_v1.parse_obj_as(Project, _response.json()) # type: ignore
|
|
261
272
|
_response_json = _response.json()
|
|
262
273
|
except JSONDecodeError:
|
|
263
274
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -295,15 +306,34 @@ class ProjectsClient:
|
|
|
295
306
|
_response = self._client_wrapper.httpx_client.request(
|
|
296
307
|
f"api/projects/{jsonable_encoder(id)}/", method="DELETE", request_options=request_options
|
|
297
308
|
)
|
|
298
|
-
if 200 <= _response.status_code < 300:
|
|
299
|
-
return
|
|
300
309
|
try:
|
|
310
|
+
if 200 <= _response.status_code < 300:
|
|
311
|
+
return
|
|
301
312
|
_response_json = _response.json()
|
|
302
313
|
except JSONDecodeError:
|
|
303
314
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
304
315
|
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
305
316
|
|
|
306
|
-
def update(
|
|
317
|
+
def update(
|
|
318
|
+
self,
|
|
319
|
+
id: int,
|
|
320
|
+
*,
|
|
321
|
+
title: typing.Optional[str] = OMIT,
|
|
322
|
+
description: typing.Optional[str] = OMIT,
|
|
323
|
+
label_config: typing.Optional[str] = OMIT,
|
|
324
|
+
expert_instruction: typing.Optional[str] = OMIT,
|
|
325
|
+
show_instruction: typing.Optional[bool] = OMIT,
|
|
326
|
+
show_skip_button: typing.Optional[bool] = OMIT,
|
|
327
|
+
enable_empty_annotation: typing.Optional[bool] = OMIT,
|
|
328
|
+
show_annotation_history: typing.Optional[bool] = OMIT,
|
|
329
|
+
reveal_preannotations_interactively: typing.Optional[bool] = OMIT,
|
|
330
|
+
show_collab_predictions: typing.Optional[bool] = OMIT,
|
|
331
|
+
maximum_annotations: typing.Optional[int] = OMIT,
|
|
332
|
+
color: typing.Optional[str] = OMIT,
|
|
333
|
+
control_weights: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
|
|
334
|
+
workspace: typing.Optional[int] = OMIT,
|
|
335
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
336
|
+
) -> ProjectsUpdateResponse:
|
|
307
337
|
"""
|
|
308
338
|
Update the project settings for a specific project. For more information, see the following:
|
|
309
339
|
|
|
@@ -324,19 +354,58 @@ class ProjectsClient:
|
|
|
324
354
|
id : int
|
|
325
355
|
A unique integer value identifying this project.
|
|
326
356
|
|
|
327
|
-
|
|
357
|
+
title : typing.Optional[str]
|
|
358
|
+
Project title
|
|
359
|
+
|
|
360
|
+
description : typing.Optional[str]
|
|
361
|
+
Project description
|
|
362
|
+
|
|
363
|
+
label_config : typing.Optional[str]
|
|
364
|
+
Label config in XML format
|
|
365
|
+
|
|
366
|
+
expert_instruction : typing.Optional[str]
|
|
367
|
+
Labeling instructions to show to the user
|
|
368
|
+
|
|
369
|
+
show_instruction : typing.Optional[bool]
|
|
370
|
+
Show labeling instructions
|
|
371
|
+
|
|
372
|
+
show_skip_button : typing.Optional[bool]
|
|
373
|
+
Show skip button
|
|
374
|
+
|
|
375
|
+
enable_empty_annotation : typing.Optional[bool]
|
|
376
|
+
Allow empty annotations
|
|
377
|
+
|
|
378
|
+
show_annotation_history : typing.Optional[bool]
|
|
379
|
+
Show annotation history
|
|
380
|
+
|
|
381
|
+
reveal_preannotations_interactively : typing.Optional[bool]
|
|
382
|
+
Reveal preannotations interactively. If set to True, predictions will be shown to the user only after selecting the area of interest
|
|
383
|
+
|
|
384
|
+
show_collab_predictions : typing.Optional[bool]
|
|
385
|
+
Show predictions to annotators
|
|
386
|
+
|
|
387
|
+
maximum_annotations : typing.Optional[int]
|
|
388
|
+
Maximum annotations per task
|
|
389
|
+
|
|
390
|
+
color : typing.Optional[str]
|
|
391
|
+
Project color in HEX format
|
|
392
|
+
|
|
393
|
+
control_weights : typing.Optional[typing.Dict[str, typing.Any]]
|
|
394
|
+
Dict of weights for each control tag in metric calculation. Each control tag (e.g. label or choice) will have its own key in control weight dict with weight for each label and overall weight. For example, if a bounding box annotation with a control tag named my_bbox should be included with 0.33 weight in agreement calculation, and the first label Car should be twice as important as Airplane, then you need to specify: {'my_bbox': {'type': 'RectangleLabels', 'labels': {'Car': 1.0, 'Airplane': 0.5}, 'overall': 0.33}
|
|
395
|
+
|
|
396
|
+
workspace : typing.Optional[int]
|
|
397
|
+
Workspace ID
|
|
328
398
|
|
|
329
399
|
request_options : typing.Optional[RequestOptions]
|
|
330
400
|
Request-specific configuration.
|
|
331
401
|
|
|
332
402
|
Returns
|
|
333
403
|
-------
|
|
334
|
-
|
|
404
|
+
ProjectsUpdateResponse
|
|
335
405
|
|
|
336
406
|
|
|
337
407
|
Examples
|
|
338
408
|
--------
|
|
339
|
-
from label_studio_sdk import Project
|
|
340
409
|
from label_studio_sdk.client import LabelStudio
|
|
341
410
|
|
|
342
411
|
client = LabelStudio(
|
|
@@ -344,19 +413,33 @@ class ProjectsClient:
|
|
|
344
413
|
)
|
|
345
414
|
client.projects.update(
|
|
346
415
|
id=1,
|
|
347
|
-
request=Project(),
|
|
348
416
|
)
|
|
349
417
|
"""
|
|
350
418
|
_response = self._client_wrapper.httpx_client.request(
|
|
351
419
|
f"api/projects/{jsonable_encoder(id)}/",
|
|
352
420
|
method="PATCH",
|
|
353
|
-
json=
|
|
421
|
+
json={
|
|
422
|
+
"title": title,
|
|
423
|
+
"description": description,
|
|
424
|
+
"label_config": label_config,
|
|
425
|
+
"expert_instruction": expert_instruction,
|
|
426
|
+
"show_instruction": show_instruction,
|
|
427
|
+
"show_skip_button": show_skip_button,
|
|
428
|
+
"enable_empty_annotation": enable_empty_annotation,
|
|
429
|
+
"show_annotation_history": show_annotation_history,
|
|
430
|
+
"reveal_preannotations_interactively": reveal_preannotations_interactively,
|
|
431
|
+
"show_collab_predictions": show_collab_predictions,
|
|
432
|
+
"maximum_annotations": maximum_annotations,
|
|
433
|
+
"color": color,
|
|
434
|
+
"control_weights": control_weights,
|
|
435
|
+
"workspace": workspace,
|
|
436
|
+
},
|
|
354
437
|
request_options=request_options,
|
|
355
438
|
omit=OMIT,
|
|
356
439
|
)
|
|
357
|
-
if 200 <= _response.status_code < 300:
|
|
358
|
-
return pydantic_v1.parse_obj_as(Project, _response.json()) # type: ignore
|
|
359
440
|
try:
|
|
441
|
+
if 200 <= _response.status_code < 300:
|
|
442
|
+
return pydantic_v1.parse_obj_as(ProjectsUpdateResponse, _response.json()) # type: ignore
|
|
360
443
|
_response_json = _response.json()
|
|
361
444
|
except JSONDecodeError:
|
|
362
445
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -473,11 +556,11 @@ class ProjectsClient:
|
|
|
473
556
|
request_options=request_options,
|
|
474
557
|
omit=OMIT,
|
|
475
558
|
)
|
|
476
|
-
if 200 <= _response.status_code < 300:
|
|
477
|
-
return pydantic_v1.parse_obj_as(ProjectsImportTasksResponse, _response.json()) # type: ignore
|
|
478
|
-
if _response.status_code == 400:
|
|
479
|
-
raise BadRequestError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
|
|
480
559
|
try:
|
|
560
|
+
if 200 <= _response.status_code < 300:
|
|
561
|
+
return pydantic_v1.parse_obj_as(ProjectsImportTasksResponse, _response.json()) # type: ignore
|
|
562
|
+
if _response.status_code == 400:
|
|
563
|
+
raise BadRequestError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
|
|
481
564
|
_response_json = _response.json()
|
|
482
565
|
except JSONDecodeError:
|
|
483
566
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -528,9 +611,9 @@ class ProjectsClient:
|
|
|
528
611
|
request_options=request_options,
|
|
529
612
|
omit=OMIT,
|
|
530
613
|
)
|
|
531
|
-
if 200 <= _response.status_code < 300:
|
|
532
|
-
return pydantic_v1.parse_obj_as(ProjectLabelConfig, _response.json()) # type: ignore
|
|
533
614
|
try:
|
|
615
|
+
if 200 <= _response.status_code < 300:
|
|
616
|
+
return pydantic_v1.parse_obj_as(ProjectLabelConfig, _response.json()) # type: ignore
|
|
534
617
|
_response_json = _response.json()
|
|
535
618
|
except JSONDecodeError:
|
|
536
619
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -596,7 +679,12 @@ class AsyncProjectsClient:
|
|
|
596
679
|
client = AsyncLabelStudio(
|
|
597
680
|
api_key="YOUR_API_KEY",
|
|
598
681
|
)
|
|
599
|
-
await client.projects.list()
|
|
682
|
+
response = await client.projects.list()
|
|
683
|
+
async for item in response:
|
|
684
|
+
yield item
|
|
685
|
+
# alternatively, you can paginate page-by-page
|
|
686
|
+
async for page in response.iter_pages():
|
|
687
|
+
yield page
|
|
600
688
|
"""
|
|
601
689
|
page = page or 1
|
|
602
690
|
_response = await self._client_wrapper.httpx_client.request(
|
|
@@ -605,20 +693,20 @@ class AsyncProjectsClient:
|
|
|
605
693
|
params={"ordering": ordering, "ids": ids, "title": title, "page": page, "page_size": page_size},
|
|
606
694
|
request_options=request_options,
|
|
607
695
|
)
|
|
608
|
-
if 200 <= _response.status_code < 300:
|
|
609
|
-
_parsed_response = pydantic_v1.parse_obj_as(ProjectsListResponse, _response.json()) # type: ignore
|
|
610
|
-
_has_next = True
|
|
611
|
-
_get_next = lambda: self.list(
|
|
612
|
-
ordering=ordering,
|
|
613
|
-
ids=ids,
|
|
614
|
-
title=title,
|
|
615
|
-
page=page + 1,
|
|
616
|
-
page_size=page_size,
|
|
617
|
-
request_options=request_options,
|
|
618
|
-
)
|
|
619
|
-
_items = _parsed_response.results
|
|
620
|
-
return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
|
|
621
696
|
try:
|
|
697
|
+
if 200 <= _response.status_code < 300:
|
|
698
|
+
_parsed_response = pydantic_v1.parse_obj_as(ProjectsListResponse, _response.json()) # type: ignore
|
|
699
|
+
_has_next = True
|
|
700
|
+
_get_next = lambda: self.list(
|
|
701
|
+
ordering=ordering,
|
|
702
|
+
ids=ids,
|
|
703
|
+
title=title,
|
|
704
|
+
page=page + 1,
|
|
705
|
+
page_size=page_size,
|
|
706
|
+
request_options=request_options,
|
|
707
|
+
)
|
|
708
|
+
_items = _parsed_response.results
|
|
709
|
+
return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
|
|
622
710
|
_response_json = _response.json()
|
|
623
711
|
except JSONDecodeError:
|
|
624
712
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -640,6 +728,7 @@ class AsyncProjectsClient:
|
|
|
640
728
|
maximum_annotations: typing.Optional[int] = OMIT,
|
|
641
729
|
color: typing.Optional[str] = OMIT,
|
|
642
730
|
control_weights: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
|
|
731
|
+
workspace: typing.Optional[int] = OMIT,
|
|
643
732
|
request_options: typing.Optional[RequestOptions] = None,
|
|
644
733
|
) -> ProjectsCreateResponse:
|
|
645
734
|
"""
|
|
@@ -694,6 +783,9 @@ class AsyncProjectsClient:
|
|
|
694
783
|
control_weights : typing.Optional[typing.Dict[str, typing.Any]]
|
|
695
784
|
Dict of weights for each control tag in metric calculation. Each control tag (e.g. label or choice) will have its own key in control weight dict with weight for each label and overall weight. For example, if a bounding box annotation with a control tag named my_bbox should be included with 0.33 weight in agreement calculation, and the first label Car should be twice as important as Airplane, then you need to specify: {'my_bbox': {'type': 'RectangleLabels', 'labels': {'Car': 1.0, 'Airplane': 0.5}, 'overall': 0.33}
|
|
696
785
|
|
|
786
|
+
workspace : typing.Optional[int]
|
|
787
|
+
Workspace ID
|
|
788
|
+
|
|
697
789
|
request_options : typing.Optional[RequestOptions]
|
|
698
790
|
Request-specific configuration.
|
|
699
791
|
|
|
@@ -728,13 +820,14 @@ class AsyncProjectsClient:
|
|
|
728
820
|
"maximum_annotations": maximum_annotations,
|
|
729
821
|
"color": color,
|
|
730
822
|
"control_weights": control_weights,
|
|
823
|
+
"workspace": workspace,
|
|
731
824
|
},
|
|
732
825
|
request_options=request_options,
|
|
733
826
|
omit=OMIT,
|
|
734
827
|
)
|
|
735
|
-
if 200 <= _response.status_code < 300:
|
|
736
|
-
return pydantic_v1.parse_obj_as(ProjectsCreateResponse, _response.json()) # type: ignore
|
|
737
828
|
try:
|
|
829
|
+
if 200 <= _response.status_code < 300:
|
|
830
|
+
return pydantic_v1.parse_obj_as(ProjectsCreateResponse, _response.json()) # type: ignore
|
|
738
831
|
_response_json = _response.json()
|
|
739
832
|
except JSONDecodeError:
|
|
740
833
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -771,9 +864,9 @@ class AsyncProjectsClient:
|
|
|
771
864
|
_response = await self._client_wrapper.httpx_client.request(
|
|
772
865
|
f"api/projects/{jsonable_encoder(id)}/", method="GET", request_options=request_options
|
|
773
866
|
)
|
|
774
|
-
if 200 <= _response.status_code < 300:
|
|
775
|
-
return pydantic_v1.parse_obj_as(Project, _response.json()) # type: ignore
|
|
776
867
|
try:
|
|
868
|
+
if 200 <= _response.status_code < 300:
|
|
869
|
+
return pydantic_v1.parse_obj_as(Project, _response.json()) # type: ignore
|
|
777
870
|
_response_json = _response.json()
|
|
778
871
|
except JSONDecodeError:
|
|
779
872
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -811,17 +904,34 @@ class AsyncProjectsClient:
|
|
|
811
904
|
_response = await self._client_wrapper.httpx_client.request(
|
|
812
905
|
f"api/projects/{jsonable_encoder(id)}/", method="DELETE", request_options=request_options
|
|
813
906
|
)
|
|
814
|
-
if 200 <= _response.status_code < 300:
|
|
815
|
-
return
|
|
816
907
|
try:
|
|
908
|
+
if 200 <= _response.status_code < 300:
|
|
909
|
+
return
|
|
817
910
|
_response_json = _response.json()
|
|
818
911
|
except JSONDecodeError:
|
|
819
912
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
820
913
|
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
821
914
|
|
|
822
915
|
async def update(
|
|
823
|
-
self,
|
|
824
|
-
|
|
916
|
+
self,
|
|
917
|
+
id: int,
|
|
918
|
+
*,
|
|
919
|
+
title: typing.Optional[str] = OMIT,
|
|
920
|
+
description: typing.Optional[str] = OMIT,
|
|
921
|
+
label_config: typing.Optional[str] = OMIT,
|
|
922
|
+
expert_instruction: typing.Optional[str] = OMIT,
|
|
923
|
+
show_instruction: typing.Optional[bool] = OMIT,
|
|
924
|
+
show_skip_button: typing.Optional[bool] = OMIT,
|
|
925
|
+
enable_empty_annotation: typing.Optional[bool] = OMIT,
|
|
926
|
+
show_annotation_history: typing.Optional[bool] = OMIT,
|
|
927
|
+
reveal_preannotations_interactively: typing.Optional[bool] = OMIT,
|
|
928
|
+
show_collab_predictions: typing.Optional[bool] = OMIT,
|
|
929
|
+
maximum_annotations: typing.Optional[int] = OMIT,
|
|
930
|
+
color: typing.Optional[str] = OMIT,
|
|
931
|
+
control_weights: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
|
|
932
|
+
workspace: typing.Optional[int] = OMIT,
|
|
933
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
934
|
+
) -> ProjectsUpdateResponse:
|
|
825
935
|
"""
|
|
826
936
|
Update the project settings for a specific project. For more information, see the following:
|
|
827
937
|
|
|
@@ -842,19 +952,58 @@ class AsyncProjectsClient:
|
|
|
842
952
|
id : int
|
|
843
953
|
A unique integer value identifying this project.
|
|
844
954
|
|
|
845
|
-
|
|
955
|
+
title : typing.Optional[str]
|
|
956
|
+
Project title
|
|
957
|
+
|
|
958
|
+
description : typing.Optional[str]
|
|
959
|
+
Project description
|
|
960
|
+
|
|
961
|
+
label_config : typing.Optional[str]
|
|
962
|
+
Label config in XML format
|
|
963
|
+
|
|
964
|
+
expert_instruction : typing.Optional[str]
|
|
965
|
+
Labeling instructions to show to the user
|
|
966
|
+
|
|
967
|
+
show_instruction : typing.Optional[bool]
|
|
968
|
+
Show labeling instructions
|
|
969
|
+
|
|
970
|
+
show_skip_button : typing.Optional[bool]
|
|
971
|
+
Show skip button
|
|
972
|
+
|
|
973
|
+
enable_empty_annotation : typing.Optional[bool]
|
|
974
|
+
Allow empty annotations
|
|
975
|
+
|
|
976
|
+
show_annotation_history : typing.Optional[bool]
|
|
977
|
+
Show annotation history
|
|
978
|
+
|
|
979
|
+
reveal_preannotations_interactively : typing.Optional[bool]
|
|
980
|
+
Reveal preannotations interactively. If set to True, predictions will be shown to the user only after selecting the area of interest
|
|
981
|
+
|
|
982
|
+
show_collab_predictions : typing.Optional[bool]
|
|
983
|
+
Show predictions to annotators
|
|
984
|
+
|
|
985
|
+
maximum_annotations : typing.Optional[int]
|
|
986
|
+
Maximum annotations per task
|
|
987
|
+
|
|
988
|
+
color : typing.Optional[str]
|
|
989
|
+
Project color in HEX format
|
|
990
|
+
|
|
991
|
+
control_weights : typing.Optional[typing.Dict[str, typing.Any]]
|
|
992
|
+
Dict of weights for each control tag in metric calculation. Each control tag (e.g. label or choice) will have its own key in control weight dict with weight for each label and overall weight. For example, if a bounding box annotation with a control tag named my_bbox should be included with 0.33 weight in agreement calculation, and the first label Car should be twice as important as Airplane, then you need to specify: {'my_bbox': {'type': 'RectangleLabels', 'labels': {'Car': 1.0, 'Airplane': 0.5}, 'overall': 0.33}
|
|
993
|
+
|
|
994
|
+
workspace : typing.Optional[int]
|
|
995
|
+
Workspace ID
|
|
846
996
|
|
|
847
997
|
request_options : typing.Optional[RequestOptions]
|
|
848
998
|
Request-specific configuration.
|
|
849
999
|
|
|
850
1000
|
Returns
|
|
851
1001
|
-------
|
|
852
|
-
|
|
1002
|
+
ProjectsUpdateResponse
|
|
853
1003
|
|
|
854
1004
|
|
|
855
1005
|
Examples
|
|
856
1006
|
--------
|
|
857
|
-
from label_studio_sdk import Project
|
|
858
1007
|
from label_studio_sdk.client import AsyncLabelStudio
|
|
859
1008
|
|
|
860
1009
|
client = AsyncLabelStudio(
|
|
@@ -862,19 +1011,33 @@ class AsyncProjectsClient:
|
|
|
862
1011
|
)
|
|
863
1012
|
await client.projects.update(
|
|
864
1013
|
id=1,
|
|
865
|
-
request=Project(),
|
|
866
1014
|
)
|
|
867
1015
|
"""
|
|
868
1016
|
_response = await self._client_wrapper.httpx_client.request(
|
|
869
1017
|
f"api/projects/{jsonable_encoder(id)}/",
|
|
870
1018
|
method="PATCH",
|
|
871
|
-
json=
|
|
1019
|
+
json={
|
|
1020
|
+
"title": title,
|
|
1021
|
+
"description": description,
|
|
1022
|
+
"label_config": label_config,
|
|
1023
|
+
"expert_instruction": expert_instruction,
|
|
1024
|
+
"show_instruction": show_instruction,
|
|
1025
|
+
"show_skip_button": show_skip_button,
|
|
1026
|
+
"enable_empty_annotation": enable_empty_annotation,
|
|
1027
|
+
"show_annotation_history": show_annotation_history,
|
|
1028
|
+
"reveal_preannotations_interactively": reveal_preannotations_interactively,
|
|
1029
|
+
"show_collab_predictions": show_collab_predictions,
|
|
1030
|
+
"maximum_annotations": maximum_annotations,
|
|
1031
|
+
"color": color,
|
|
1032
|
+
"control_weights": control_weights,
|
|
1033
|
+
"workspace": workspace,
|
|
1034
|
+
},
|
|
872
1035
|
request_options=request_options,
|
|
873
1036
|
omit=OMIT,
|
|
874
1037
|
)
|
|
875
|
-
if 200 <= _response.status_code < 300:
|
|
876
|
-
return pydantic_v1.parse_obj_as(Project, _response.json()) # type: ignore
|
|
877
1038
|
try:
|
|
1039
|
+
if 200 <= _response.status_code < 300:
|
|
1040
|
+
return pydantic_v1.parse_obj_as(ProjectsUpdateResponse, _response.json()) # type: ignore
|
|
878
1041
|
_response_json = _response.json()
|
|
879
1042
|
except JSONDecodeError:
|
|
880
1043
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -991,11 +1154,11 @@ class AsyncProjectsClient:
|
|
|
991
1154
|
request_options=request_options,
|
|
992
1155
|
omit=OMIT,
|
|
993
1156
|
)
|
|
994
|
-
if 200 <= _response.status_code < 300:
|
|
995
|
-
return pydantic_v1.parse_obj_as(ProjectsImportTasksResponse, _response.json()) # type: ignore
|
|
996
|
-
if _response.status_code == 400:
|
|
997
|
-
raise BadRequestError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
|
|
998
1157
|
try:
|
|
1158
|
+
if 200 <= _response.status_code < 300:
|
|
1159
|
+
return pydantic_v1.parse_obj_as(ProjectsImportTasksResponse, _response.json()) # type: ignore
|
|
1160
|
+
if _response.status_code == 400:
|
|
1161
|
+
raise BadRequestError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
|
|
999
1162
|
_response_json = _response.json()
|
|
1000
1163
|
except JSONDecodeError:
|
|
1001
1164
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -1046,9 +1209,9 @@ class AsyncProjectsClient:
|
|
|
1046
1209
|
request_options=request_options,
|
|
1047
1210
|
omit=OMIT,
|
|
1048
1211
|
)
|
|
1049
|
-
if 200 <= _response.status_code < 300:
|
|
1050
|
-
return pydantic_v1.parse_obj_as(ProjectLabelConfig, _response.json()) # type: ignore
|
|
1051
1212
|
try:
|
|
1213
|
+
if 200 <= _response.status_code < 300:
|
|
1214
|
+
return pydantic_v1.parse_obj_as(ProjectLabelConfig, _response.json()) # type: ignore
|
|
1052
1215
|
_response_json = _response.json()
|
|
1053
1216
|
except JSONDecodeError:
|
|
1054
1217
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
from typing_extensions import Annotated
|
|
1
3
|
from .client import ProjectsClient, AsyncProjectsClient
|
|
2
|
-
|
|
4
|
+
from pydantic import model_validator, validator, Field, ConfigDict
|
|
3
5
|
from label_studio_sdk._extensions.pager_ext import SyncPagerExt, AsyncPagerExt, T
|
|
6
|
+
from label_studio_sdk.types.project import Project
|
|
7
|
+
from label_studio_sdk.label_interface import LabelInterface
|
|
8
|
+
|
|
9
|
+
from ..core import RequestOptions
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ProjectExt(Project):
|
|
13
|
+
|
|
14
|
+
def get_label_interface(self):
|
|
15
|
+
return LabelInterface(self.label_config)
|
|
4
16
|
|
|
5
17
|
|
|
6
18
|
class ProjectsClientExt(ProjectsClient):
|
|
@@ -10,6 +22,9 @@ class ProjectsClientExt(ProjectsClient):
|
|
|
10
22
|
|
|
11
23
|
list.__doc__ = ProjectsClient.list.__doc__
|
|
12
24
|
|
|
25
|
+
def get(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> ProjectExt:
|
|
26
|
+
return ProjectExt(**dict(super().get(id, request_options=request_options)))
|
|
27
|
+
|
|
13
28
|
|
|
14
29
|
class AsyncProjectsClientExt(AsyncProjectsClient):
|
|
15
30
|
|