label-studio-sdk 2.0.4__py3-none-any.whl → 2.0.5__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.

Files changed (37) hide show
  1. label_studio_sdk/__init__.py +10 -0
  2. label_studio_sdk/activity_logs/__init__.py +5 -0
  3. label_studio_sdk/activity_logs/client.py +246 -0
  4. label_studio_sdk/activity_logs/types/__init__.py +5 -0
  5. label_studio_sdk/activity_logs/types/activity_logs_list_request_method.py +5 -0
  6. label_studio_sdk/base_client.py +4 -0
  7. label_studio_sdk/errors/internal_server_error.py +2 -1
  8. label_studio_sdk/ml/client.py +4 -4
  9. label_studio_sdk/projects/__init__.py +14 -2
  10. label_studio_sdk/projects/client.py +4 -0
  11. label_studio_sdk/projects/metrics/__init__.py +6 -0
  12. label_studio_sdk/projects/metrics/client.py +282 -0
  13. label_studio_sdk/projects/metrics/custom/__init__.py +5 -0
  14. label_studio_sdk/projects/metrics/custom/client.py +535 -0
  15. label_studio_sdk/projects/metrics/custom/types/__init__.py +5 -0
  16. label_studio_sdk/projects/metrics/custom/types/custom_get_lambda_response.py +19 -0
  17. label_studio_sdk/projects/stats/__init__.py +18 -2
  18. label_studio_sdk/projects/stats/client.py +129 -0
  19. label_studio_sdk/projects/stats/types/__init__.py +12 -1
  20. label_studio_sdk/projects/stats/types/stats_total_agreement_response.py +7 -0
  21. label_studio_sdk/projects/stats/types/stats_total_agreement_response_one.py +19 -0
  22. label_studio_sdk/projects/stats/types/stats_total_agreement_response_zero.py +19 -0
  23. label_studio_sdk/types/__init__.py +6 -0
  24. label_studio_sdk/types/activity_log.py +49 -0
  25. label_studio_sdk/types/activity_log_response.py +28 -0
  26. label_studio_sdk/types/metric_param.py +31 -0
  27. label_studio_sdk/workspaces/members/__init__.py +4 -0
  28. label_studio_sdk/workspaces/members/bulk/__init__.py +5 -0
  29. label_studio_sdk/workspaces/members/bulk/client.py +273 -0
  30. label_studio_sdk/workspaces/members/bulk/types/__init__.py +6 -0
  31. label_studio_sdk/workspaces/members/bulk/types/bulk_delete_response.py +19 -0
  32. label_studio_sdk/workspaces/members/bulk/types/bulk_post_response.py +19 -0
  33. label_studio_sdk/workspaces/members/client.py +4 -0
  34. {label_studio_sdk-2.0.4.dist-info → label_studio_sdk-2.0.5.dist-info}/METADATA +1 -1
  35. {label_studio_sdk-2.0.4.dist-info → label_studio_sdk-2.0.5.dist-info}/RECORD +37 -16
  36. {label_studio_sdk-2.0.4.dist-info → label_studio_sdk-2.0.5.dist-info}/LICENSE +0 -0
  37. {label_studio_sdk-2.0.4.dist-info → label_studio_sdk-2.0.5.dist-info}/WHEEL +0 -0
@@ -8,6 +8,7 @@ from ...core.jsonable_encoder import jsonable_encoder
8
8
  from ...core.unchecked_base_model import construct_type
9
9
  from json.decoder import JSONDecodeError
10
10
  from ...core.api_error import ApiError
11
+ from .types.stats_total_agreement_response import StatsTotalAgreementResponse
11
12
  from ...core.client_wrapper import AsyncClientWrapper
12
13
 
13
14
 
@@ -88,6 +89,66 @@ class StatsClient:
88
89
  raise ApiError(status_code=_response.status_code, body=_response.text)
89
90
  raise ApiError(status_code=_response.status_code, body=_response_json)
90
91
 
92
+ def total_agreement(
93
+ self,
94
+ id: int,
95
+ *,
96
+ per_label: typing.Optional[bool] = None,
97
+ request_options: typing.Optional[RequestOptions] = None,
98
+ ) -> StatsTotalAgreementResponse:
99
+ """
100
+ Overall or per-label total agreement across the project.
101
+
102
+ NOTE: due to an open issue in Fern, SDK clients will raise ApiError upon handling a 204 response. As a workaround, wrap call to this function in a try-except block.
103
+
104
+ Parameters
105
+ ----------
106
+ id : int
107
+
108
+ per_label : typing.Optional[bool]
109
+ Return agreement per label
110
+
111
+ request_options : typing.Optional[RequestOptions]
112
+ Request-specific configuration.
113
+
114
+ Returns
115
+ -------
116
+ StatsTotalAgreementResponse
117
+ Total agreement
118
+
119
+ Examples
120
+ --------
121
+ from label_studio_sdk import LabelStudio
122
+
123
+ client = LabelStudio(
124
+ api_key="YOUR_API_KEY",
125
+ )
126
+ client.projects.stats.total_agreement(
127
+ id=1,
128
+ )
129
+ """
130
+ _response = self._client_wrapper.httpx_client.request(
131
+ f"api/projects/{jsonable_encoder(id)}/stats/total_agreement",
132
+ method="GET",
133
+ params={
134
+ "per_label": per_label,
135
+ },
136
+ request_options=request_options,
137
+ )
138
+ try:
139
+ if 200 <= _response.status_code < 300:
140
+ return typing.cast(
141
+ StatsTotalAgreementResponse,
142
+ construct_type(
143
+ type_=StatsTotalAgreementResponse, # type: ignore
144
+ object_=_response.json(),
145
+ ),
146
+ )
147
+ _response_json = _response.json()
148
+ except JSONDecodeError:
149
+ raise ApiError(status_code=_response.status_code, body=_response.text)
150
+ raise ApiError(status_code=_response.status_code, body=_response_json)
151
+
91
152
 
92
153
  class AsyncStatsClient:
93
154
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -173,3 +234,71 @@ class AsyncStatsClient:
173
234
  except JSONDecodeError:
174
235
  raise ApiError(status_code=_response.status_code, body=_response.text)
175
236
  raise ApiError(status_code=_response.status_code, body=_response_json)
237
+
238
+ async def total_agreement(
239
+ self,
240
+ id: int,
241
+ *,
242
+ per_label: typing.Optional[bool] = None,
243
+ request_options: typing.Optional[RequestOptions] = None,
244
+ ) -> StatsTotalAgreementResponse:
245
+ """
246
+ Overall or per-label total agreement across the project.
247
+
248
+ NOTE: due to an open issue in Fern, SDK clients will raise ApiError upon handling a 204 response. As a workaround, wrap call to this function in a try-except block.
249
+
250
+ Parameters
251
+ ----------
252
+ id : int
253
+
254
+ per_label : typing.Optional[bool]
255
+ Return agreement per label
256
+
257
+ request_options : typing.Optional[RequestOptions]
258
+ Request-specific configuration.
259
+
260
+ Returns
261
+ -------
262
+ StatsTotalAgreementResponse
263
+ Total agreement
264
+
265
+ Examples
266
+ --------
267
+ import asyncio
268
+
269
+ from label_studio_sdk import AsyncLabelStudio
270
+
271
+ client = AsyncLabelStudio(
272
+ api_key="YOUR_API_KEY",
273
+ )
274
+
275
+
276
+ async def main() -> None:
277
+ await client.projects.stats.total_agreement(
278
+ id=1,
279
+ )
280
+
281
+
282
+ asyncio.run(main())
283
+ """
284
+ _response = await self._client_wrapper.httpx_client.request(
285
+ f"api/projects/{jsonable_encoder(id)}/stats/total_agreement",
286
+ method="GET",
287
+ params={
288
+ "per_label": per_label,
289
+ },
290
+ request_options=request_options,
291
+ )
292
+ try:
293
+ if 200 <= _response.status_code < 300:
294
+ return typing.cast(
295
+ StatsTotalAgreementResponse,
296
+ construct_type(
297
+ type_=StatsTotalAgreementResponse, # type: ignore
298
+ object_=_response.json(),
299
+ ),
300
+ )
301
+ _response_json = _response.json()
302
+ except JSONDecodeError:
303
+ raise ApiError(status_code=_response.status_code, body=_response.text)
304
+ raise ApiError(status_code=_response.status_code, body=_response_json)
@@ -4,5 +4,16 @@ from .stats_iaa_response import StatsIaaResponse
4
4
  from .stats_iaa_response_common_tasks import StatsIaaResponseCommonTasks
5
5
  from .stats_iaa_response_iaa import StatsIaaResponseIaa
6
6
  from .stats_iaa_response_std import StatsIaaResponseStd
7
+ from .stats_total_agreement_response import StatsTotalAgreementResponse
8
+ from .stats_total_agreement_response_one import StatsTotalAgreementResponseOne
9
+ from .stats_total_agreement_response_zero import StatsTotalAgreementResponseZero
7
10
 
8
- __all__ = ["StatsIaaResponse", "StatsIaaResponseCommonTasks", "StatsIaaResponseIaa", "StatsIaaResponseStd"]
11
+ __all__ = [
12
+ "StatsIaaResponse",
13
+ "StatsIaaResponseCommonTasks",
14
+ "StatsIaaResponseIaa",
15
+ "StatsIaaResponseStd",
16
+ "StatsTotalAgreementResponse",
17
+ "StatsTotalAgreementResponseOne",
18
+ "StatsTotalAgreementResponseZero",
19
+ ]
@@ -0,0 +1,7 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from .stats_total_agreement_response_zero import StatsTotalAgreementResponseZero
5
+ from .stats_total_agreement_response_one import StatsTotalAgreementResponseOne
6
+
7
+ StatsTotalAgreementResponse = typing.Union[StatsTotalAgreementResponseZero, StatsTotalAgreementResponseOne]
@@ -0,0 +1,19 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ....core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2
6
+ import pydantic
7
+
8
+
9
+ class StatsTotalAgreementResponseOne(UncheckedBaseModel):
10
+ total_agreement: typing.Optional[typing.Dict[str, float]] = None
11
+
12
+ if IS_PYDANTIC_V2:
13
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
14
+ else:
15
+
16
+ class Config:
17
+ frozen = True
18
+ smart_union = True
19
+ extra = pydantic.Extra.allow
@@ -0,0 +1,19 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ....core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2
6
+ import pydantic
7
+
8
+
9
+ class StatsTotalAgreementResponseZero(UncheckedBaseModel):
10
+ total_agreement: typing.Optional[float] = None
11
+
12
+ if IS_PYDANTIC_V2:
13
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
14
+ else:
15
+
16
+ class Config:
17
+ frozen = True
18
+ smart_union = True
19
+ extra = pydantic.Extra.allow
@@ -1,6 +1,8 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  from .actions_enum import ActionsEnum
4
+ from .activity_log import ActivityLog
5
+ from .activity_log_response import ActivityLogResponse
4
6
  from .all_roles_project_list import AllRolesProjectList
5
7
  from .all_roles_project_list_sampling import AllRolesProjectListSampling
6
8
  from .all_roles_project_list_skip_queue import AllRolesProjectListSkipQueue
@@ -99,6 +101,7 @@ from .lseapi_token_create import LseapiTokenCreate
99
101
  from .lseapi_token_list import LseapiTokenList
100
102
  from .lsejwt_settings import LsejwtSettings
101
103
  from .maybe_expanded_comment import MaybeExpandedComment
104
+ from .metric_param import MetricParam
102
105
  from .ml_backend import MlBackend
103
106
  from .mode_enum import ModeEnum
104
107
  from .model_interface import ModelInterface
@@ -192,6 +195,8 @@ from .workspace_member_list import WorkspaceMemberList
192
195
 
193
196
  __all__ = [
194
197
  "ActionsEnum",
198
+ "ActivityLog",
199
+ "ActivityLogResponse",
195
200
  "AllRolesProjectList",
196
201
  "AllRolesProjectListSampling",
197
202
  "AllRolesProjectListSkipQueue",
@@ -288,6 +293,7 @@ __all__ = [
288
293
  "LseapiTokenList",
289
294
  "LsejwtSettings",
290
295
  "MaybeExpandedComment",
296
+ "MetricParam",
291
297
  "MlBackend",
292
298
  "ModeEnum",
293
299
  "ModelInterface",
@@ -0,0 +1,49 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.unchecked_base_model import UncheckedBaseModel
4
+ import datetime as dt
5
+ import typing
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
8
+
9
+
10
+ class ActivityLog(UncheckedBaseModel):
11
+ datetime: dt.datetime
12
+ duration: typing.Optional[int] = pydantic.Field(default=None)
13
+ """
14
+ Duration of response generation in ms
15
+ """
16
+
17
+ email: str
18
+ extra_data: typing.Optional[typing.Optional[typing.Any]] = None
19
+ http_referer: typing.Optional[str] = None
20
+ id: int
21
+ ip_address: typing.Optional[str] = None
22
+ organization_id: typing.Optional[int] = pydantic.Field(default=None)
23
+ """
24
+ Organization id
25
+ """
26
+
27
+ project_id: typing.Optional[int] = pydantic.Field(default=None)
28
+ """
29
+ Project id if request has it
30
+ """
31
+
32
+ request_method: str
33
+ request_url: str
34
+ response_code: str
35
+ user_agent: typing.Optional[str] = None
36
+ user_id: int
37
+ workspace_owner_id: typing.Optional[int] = pydantic.Field(default=None)
38
+ """
39
+ Owner id of workspace where action performed
40
+ """
41
+
42
+ if IS_PYDANTIC_V2:
43
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
44
+ else:
45
+
46
+ class Config:
47
+ frozen = True
48
+ smart_union = True
49
+ extra = pydantic.Extra.allow
@@ -0,0 +1,28 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ from .activity_log import ActivityLog
6
+ import typing_extensions
7
+ from ..core.serialization import FieldMetadata
8
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
9
+ import pydantic
10
+
11
+
12
+ class ActivityLogResponse(UncheckedBaseModel):
13
+ """
14
+ Serializer for ActivityLogAPI response.
15
+ """
16
+
17
+ data: typing.List[ActivityLog]
18
+ records_filtered: typing_extensions.Annotated[int, FieldMetadata(alias="recordsFiltered")]
19
+ records_total: typing_extensions.Annotated[int, FieldMetadata(alias="recordsTotal")]
20
+
21
+ if IS_PYDANTIC_V2:
22
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
23
+ else:
24
+
25
+ class Config:
26
+ frozen = True
27
+ smart_union = True
28
+ extra = pydantic.Extra.allow
@@ -0,0 +1,31 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+
8
+
9
+ class MetricParam(UncheckedBaseModel):
10
+ agreement_threshold: str
11
+ allowed: str
12
+ max_additional_annotators_assignable: typing.Optional[int] = pydantic.Field(default=None)
13
+ """
14
+ Maximum number of additional annotators that can be assigned to a low agreement task
15
+ """
16
+
17
+ metric_name: typing.Optional[str] = pydantic.Field(default=None)
18
+ """
19
+ Evaluation metric chosen for this project
20
+ """
21
+
22
+ metric_params: typing.Optional[typing.Optional[typing.Any]] = None
23
+
24
+ if IS_PYDANTIC_V2:
25
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
26
+ else:
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ extra = pydantic.Extra.allow
@@ -1,2 +1,6 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ from . import bulk
4
+ from .bulk import BulkDeleteResponse, BulkPostResponse
5
+
6
+ __all__ = ["BulkDeleteResponse", "BulkPostResponse", "bulk"]
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .types import BulkDeleteResponse, BulkPostResponse
4
+
5
+ __all__ = ["BulkDeleteResponse", "BulkPostResponse"]
@@ -0,0 +1,273 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from ....core.client_wrapper import SyncClientWrapper
5
+ from ....core.request_options import RequestOptions
6
+ from .types.bulk_post_response import BulkPostResponse
7
+ from ....core.jsonable_encoder import jsonable_encoder
8
+ from ....core.unchecked_base_model import construct_type
9
+ from json.decoder import JSONDecodeError
10
+ from ....core.api_error import ApiError
11
+ from .types.bulk_delete_response import BulkDeleteResponse
12
+ from ....core.client_wrapper import AsyncClientWrapper
13
+
14
+ # this is used as the default value for optional parameters
15
+ OMIT = typing.cast(typing.Any, ...)
16
+
17
+
18
+ class BulkClient:
19
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
20
+ self._client_wrapper = client_wrapper
21
+
22
+ def post(
23
+ self,
24
+ id: int,
25
+ *,
26
+ all_: bool,
27
+ excluded: typing.Optional[typing.Sequence[int]] = OMIT,
28
+ included: typing.Optional[typing.Sequence[int]] = OMIT,
29
+ request_options: typing.Optional[RequestOptions] = None,
30
+ ) -> BulkPostResponse:
31
+ """
32
+ Assign workspace members in bulk.
33
+
34
+ Parameters
35
+ ----------
36
+ id : int
37
+
38
+ all_ : bool
39
+
40
+ excluded : typing.Optional[typing.Sequence[int]]
41
+
42
+ included : typing.Optional[typing.Sequence[int]]
43
+
44
+ request_options : typing.Optional[RequestOptions]
45
+ Request-specific configuration.
46
+
47
+ Returns
48
+ -------
49
+ BulkPostResponse
50
+
51
+
52
+ Examples
53
+ --------
54
+ from label_studio_sdk import LabelStudio
55
+
56
+ client = LabelStudio(
57
+ api_key="YOUR_API_KEY",
58
+ )
59
+ client.workspaces.members.bulk.post(
60
+ id=1,
61
+ all_=True,
62
+ )
63
+ """
64
+ _response = self._client_wrapper.httpx_client.request(
65
+ f"api/workspaces/{jsonable_encoder(id)}/memberships/bulk/",
66
+ method="POST",
67
+ json={
68
+ "all": all_,
69
+ "excluded": excluded,
70
+ "included": included,
71
+ },
72
+ headers={
73
+ "content-type": "application/json",
74
+ },
75
+ request_options=request_options,
76
+ omit=OMIT,
77
+ )
78
+ try:
79
+ if 200 <= _response.status_code < 300:
80
+ return typing.cast(
81
+ BulkPostResponse,
82
+ construct_type(
83
+ type_=BulkPostResponse, # type: ignore
84
+ object_=_response.json(),
85
+ ),
86
+ )
87
+ _response_json = _response.json()
88
+ except JSONDecodeError:
89
+ raise ApiError(status_code=_response.status_code, body=_response.text)
90
+ raise ApiError(status_code=_response.status_code, body=_response_json)
91
+
92
+ def delete(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> BulkDeleteResponse:
93
+ """
94
+ Unassign workspace members in bulk. Allows the same request body as bulk assign.
95
+
96
+ Parameters
97
+ ----------
98
+ id : int
99
+
100
+ request_options : typing.Optional[RequestOptions]
101
+ Request-specific configuration.
102
+
103
+ Returns
104
+ -------
105
+ BulkDeleteResponse
106
+
107
+
108
+ Examples
109
+ --------
110
+ from label_studio_sdk import LabelStudio
111
+
112
+ client = LabelStudio(
113
+ api_key="YOUR_API_KEY",
114
+ )
115
+ client.workspaces.members.bulk.delete(
116
+ id=1,
117
+ )
118
+ """
119
+ _response = self._client_wrapper.httpx_client.request(
120
+ f"api/workspaces/{jsonable_encoder(id)}/memberships/bulk/",
121
+ method="DELETE",
122
+ request_options=request_options,
123
+ )
124
+ try:
125
+ if 200 <= _response.status_code < 300:
126
+ return typing.cast(
127
+ BulkDeleteResponse,
128
+ construct_type(
129
+ type_=BulkDeleteResponse, # type: ignore
130
+ object_=_response.json(),
131
+ ),
132
+ )
133
+ _response_json = _response.json()
134
+ except JSONDecodeError:
135
+ raise ApiError(status_code=_response.status_code, body=_response.text)
136
+ raise ApiError(status_code=_response.status_code, body=_response_json)
137
+
138
+
139
+ class AsyncBulkClient:
140
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
141
+ self._client_wrapper = client_wrapper
142
+
143
+ async def post(
144
+ self,
145
+ id: int,
146
+ *,
147
+ all_: bool,
148
+ excluded: typing.Optional[typing.Sequence[int]] = OMIT,
149
+ included: typing.Optional[typing.Sequence[int]] = OMIT,
150
+ request_options: typing.Optional[RequestOptions] = None,
151
+ ) -> BulkPostResponse:
152
+ """
153
+ Assign workspace members in bulk.
154
+
155
+ Parameters
156
+ ----------
157
+ id : int
158
+
159
+ all_ : bool
160
+
161
+ excluded : typing.Optional[typing.Sequence[int]]
162
+
163
+ included : typing.Optional[typing.Sequence[int]]
164
+
165
+ request_options : typing.Optional[RequestOptions]
166
+ Request-specific configuration.
167
+
168
+ Returns
169
+ -------
170
+ BulkPostResponse
171
+
172
+
173
+ Examples
174
+ --------
175
+ import asyncio
176
+
177
+ from label_studio_sdk import AsyncLabelStudio
178
+
179
+ client = AsyncLabelStudio(
180
+ api_key="YOUR_API_KEY",
181
+ )
182
+
183
+
184
+ async def main() -> None:
185
+ await client.workspaces.members.bulk.post(
186
+ id=1,
187
+ all_=True,
188
+ )
189
+
190
+
191
+ asyncio.run(main())
192
+ """
193
+ _response = await self._client_wrapper.httpx_client.request(
194
+ f"api/workspaces/{jsonable_encoder(id)}/memberships/bulk/",
195
+ method="POST",
196
+ json={
197
+ "all": all_,
198
+ "excluded": excluded,
199
+ "included": included,
200
+ },
201
+ headers={
202
+ "content-type": "application/json",
203
+ },
204
+ request_options=request_options,
205
+ omit=OMIT,
206
+ )
207
+ try:
208
+ if 200 <= _response.status_code < 300:
209
+ return typing.cast(
210
+ BulkPostResponse,
211
+ construct_type(
212
+ type_=BulkPostResponse, # type: ignore
213
+ object_=_response.json(),
214
+ ),
215
+ )
216
+ _response_json = _response.json()
217
+ except JSONDecodeError:
218
+ raise ApiError(status_code=_response.status_code, body=_response.text)
219
+ raise ApiError(status_code=_response.status_code, body=_response_json)
220
+
221
+ async def delete(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> BulkDeleteResponse:
222
+ """
223
+ Unassign workspace members in bulk. Allows the same request body as bulk assign.
224
+
225
+ Parameters
226
+ ----------
227
+ id : int
228
+
229
+ request_options : typing.Optional[RequestOptions]
230
+ Request-specific configuration.
231
+
232
+ Returns
233
+ -------
234
+ BulkDeleteResponse
235
+
236
+
237
+ Examples
238
+ --------
239
+ import asyncio
240
+
241
+ from label_studio_sdk import AsyncLabelStudio
242
+
243
+ client = AsyncLabelStudio(
244
+ api_key="YOUR_API_KEY",
245
+ )
246
+
247
+
248
+ async def main() -> None:
249
+ await client.workspaces.members.bulk.delete(
250
+ id=1,
251
+ )
252
+
253
+
254
+ asyncio.run(main())
255
+ """
256
+ _response = await self._client_wrapper.httpx_client.request(
257
+ f"api/workspaces/{jsonable_encoder(id)}/memberships/bulk/",
258
+ method="DELETE",
259
+ request_options=request_options,
260
+ )
261
+ try:
262
+ if 200 <= _response.status_code < 300:
263
+ return typing.cast(
264
+ BulkDeleteResponse,
265
+ construct_type(
266
+ type_=BulkDeleteResponse, # type: ignore
267
+ object_=_response.json(),
268
+ ),
269
+ )
270
+ _response_json = _response.json()
271
+ except JSONDecodeError:
272
+ raise ApiError(status_code=_response.status_code, body=_response.text)
273
+ raise ApiError(status_code=_response.status_code, body=_response_json)
@@ -0,0 +1,6 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .bulk_delete_response import BulkDeleteResponse
4
+ from .bulk_post_response import BulkPostResponse
5
+
6
+ __all__ = ["BulkDeleteResponse", "BulkPostResponse"]
@@ -0,0 +1,19 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .....core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ from .....core.pydantic_utilities import IS_PYDANTIC_V2
6
+ import pydantic
7
+
8
+
9
+ class BulkDeleteResponse(UncheckedBaseModel):
10
+ unassignments: typing.Optional[int] = None
11
+
12
+ if IS_PYDANTIC_V2:
13
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
14
+ else:
15
+
16
+ class Config:
17
+ frozen = True
18
+ smart_union = True
19
+ extra = pydantic.Extra.allow
@@ -0,0 +1,19 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .....core.unchecked_base_model import UncheckedBaseModel
4
+ import typing
5
+ from .....core.pydantic_utilities import IS_PYDANTIC_V2
6
+ import pydantic
7
+
8
+
9
+ class BulkPostResponse(UncheckedBaseModel):
10
+ assignments: typing.Optional[int] = None
11
+
12
+ if IS_PYDANTIC_V2:
13
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
14
+ else:
15
+
16
+ class Config:
17
+ frozen = True
18
+ smart_union = True
19
+ extra = pydantic.Extra.allow