label-studio-sdk 2.0.6__py3-none-any.whl → 2.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.
- label_studio_sdk/__init__.py +32 -2
- label_studio_sdk/base_client.py +4 -0
- label_studio_sdk/converter/exports/yolo.py +89 -74
- label_studio_sdk/core/client_wrapper.py +1 -1
- label_studio_sdk/import_storage/azure_spi/client.py +30 -0
- label_studio_sdk/label_interface/control_tags.py +38 -0
- label_studio_sdk/label_interface/data_examples.json +10 -0
- label_studio_sdk/label_interface/interface.py +13 -0
- label_studio_sdk/label_interface/object_tags.py +9 -0
- label_studio_sdk/ml/client.py +124 -0
- label_studio_sdk/organizations/__init__.py +3 -2
- label_studio_sdk/organizations/client.py +540 -1
- label_studio_sdk/organizations/invites/__init__.py +2 -0
- label_studio_sdk/organizations/invites/client.py +368 -0
- label_studio_sdk/organizations/permissions/__init__.py +2 -0
- label_studio_sdk/organizations/permissions/client.py +1129 -0
- label_studio_sdk/organizations/types/__init__.py +5 -0
- label_studio_sdk/organizations/types/patched_default_role_request_custom_scripts_editable_by.py +7 -0
- label_studio_sdk/project_templates/__init__.py +2 -0
- label_studio_sdk/project_templates/client.py +909 -0
- label_studio_sdk/projects/__init__.py +30 -0
- label_studio_sdk/projects/client.py +355 -0
- label_studio_sdk/projects/stats/__init__.py +28 -0
- label_studio_sdk/projects/stats/client.py +1002 -43
- label_studio_sdk/projects/stats/types/__init__.py +30 -0
- label_studio_sdk/projects/stats/types/stats_agreement_annotator_response.py +26 -0
- label_studio_sdk/projects/stats/types/stats_data_filters_response.py +23 -0
- label_studio_sdk/projects/stats/types/stats_data_filters_response_user_filters.py +34 -0
- label_studio_sdk/projects/stats/types/stats_data_filters_response_user_filters_stats_item.py +22 -0
- label_studio_sdk/projects/stats/types/stats_finished_tasks_response.py +32 -0
- label_studio_sdk/projects/stats/types/stats_lead_time_response.py +23 -0
- label_studio_sdk/projects/stats/types/stats_lead_time_response_lead_time_stats_item.py +37 -0
- label_studio_sdk/projects/stats/types/stats_user_ground_truth_agreement_response.py +20 -0
- label_studio_sdk/projects/stats/types/stats_user_ground_truth_agreement_response_agreement.py +5 -0
- label_studio_sdk/projects/stats/types/stats_user_prediction_agreement_response.py +24 -0
- label_studio_sdk/projects/stats/types/stats_user_prediction_agreement_response_average_prediction_agreement_per_user.py +5 -0
- label_studio_sdk/projects/stats/types/stats_user_review_score_response.py +22 -0
- label_studio_sdk/projects/stats/types/stats_user_review_score_response_performance_score.py +5 -0
- label_studio_sdk/projects/stats/types/stats_user_review_score_response_review_score.py +5 -0
- label_studio_sdk/projects/types/__init__.py +2 -0
- label_studio_sdk/projects/types/projects_import_predictions_response.py +26 -0
- label_studio_sdk/prompts/versions/client.py +4 -16
- label_studio_sdk/types/__init__.py +26 -2
- label_studio_sdk/types/azure_service_principal_import_storage.py +5 -0
- label_studio_sdk/types/azure_service_principal_import_storage_request.py +5 -0
- label_studio_sdk/types/configurable_permission_option.py +25 -0
- label_studio_sdk/types/configurable_permission_option_default.py +7 -0
- label_studio_sdk/types/default_role.py +75 -0
- label_studio_sdk/types/default_role_custom_scripts_editable_by.py +7 -0
- label_studio_sdk/types/lse_organization.py +2 -2
- label_studio_sdk/types/lse_project.py +223 -0
- label_studio_sdk/types/lse_project_counts.py +46 -0
- label_studio_sdk/types/lse_project_sampling.py +7 -0
- label_studio_sdk/types/lse_project_skip_queue.py +7 -0
- label_studio_sdk/types/lse_task.py +1 -1
- label_studio_sdk/types/lse_task_serializer_for_reviewers.py +1 -1
- label_studio_sdk/types/organization_permission.py +31 -0
- label_studio_sdk/types/organization_permission_request.py +24 -0
- label_studio_sdk/types/paginated_lse_project_counts_list.py +23 -0
- label_studio_sdk/types/project_template.py +41 -0
- label_studio_sdk/types/project_template_request.py +38 -0
- label_studio_sdk/types/who_am_i_user.py +1 -0
- {label_studio_sdk-2.0.6.dist-info → label_studio_sdk-2.0.8.dist-info}/METADATA +1 -1
- {label_studio_sdk-2.0.6.dist-info → label_studio_sdk-2.0.8.dist-info}/RECORD +66 -31
- label_studio_sdk/types/default_role_enum.py +0 -5
- {label_studio_sdk-2.0.6.dist-info → label_studio_sdk-2.0.8.dist-info}/LICENSE +0 -0
- {label_studio_sdk-2.0.6.dist-info → label_studio_sdk-2.0.8.dist-info}/WHEEL +0 -0
|
@@ -8,7 +8,14 @@ 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_agreement_annotator_response import StatsAgreementAnnotatorResponse
|
|
12
|
+
from .types.stats_data_filters_response import StatsDataFiltersResponse
|
|
13
|
+
from .types.stats_finished_tasks_response import StatsFinishedTasksResponse
|
|
14
|
+
from .types.stats_lead_time_response import StatsLeadTimeResponse
|
|
11
15
|
from .types.stats_total_agreement_response import StatsTotalAgreementResponse
|
|
16
|
+
from .types.stats_user_prediction_agreement_response import StatsUserPredictionAgreementResponse
|
|
17
|
+
from .types.stats_user_review_score_response import StatsUserReviewScoreResponse
|
|
18
|
+
from .types.stats_user_ground_truth_agreement_response import StatsUserGroundTruthAgreementResponse
|
|
12
19
|
from ...core.client_wrapper import AsyncClientWrapper
|
|
13
20
|
|
|
14
21
|
|
|
@@ -89,6 +96,205 @@ class StatsClient:
|
|
|
89
96
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
90
97
|
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
91
98
|
|
|
99
|
+
def agreement_annotator(
|
|
100
|
+
self, id: int, user_id: int, *, request_options: typing.Optional[RequestOptions] = None
|
|
101
|
+
) -> StatsAgreementAnnotatorResponse:
|
|
102
|
+
"""
|
|
103
|
+
Get agreement statistics for a specific annotator within a project.
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
id : int
|
|
108
|
+
|
|
109
|
+
user_id : int
|
|
110
|
+
|
|
111
|
+
request_options : typing.Optional[RequestOptions]
|
|
112
|
+
Request-specific configuration.
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
StatsAgreementAnnotatorResponse
|
|
117
|
+
Individual annotator agreement statistics
|
|
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.agreement_annotator(
|
|
127
|
+
id=1,
|
|
128
|
+
user_id=1,
|
|
129
|
+
)
|
|
130
|
+
"""
|
|
131
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
132
|
+
f"api/projects/{jsonable_encoder(id)}/stats/agreement_annotator/{jsonable_encoder(user_id)}",
|
|
133
|
+
method="GET",
|
|
134
|
+
request_options=request_options,
|
|
135
|
+
)
|
|
136
|
+
try:
|
|
137
|
+
if 200 <= _response.status_code < 300:
|
|
138
|
+
return typing.cast(
|
|
139
|
+
StatsAgreementAnnotatorResponse,
|
|
140
|
+
construct_type(
|
|
141
|
+
type_=StatsAgreementAnnotatorResponse, # type: ignore
|
|
142
|
+
object_=_response.json(),
|
|
143
|
+
),
|
|
144
|
+
)
|
|
145
|
+
_response_json = _response.json()
|
|
146
|
+
except JSONDecodeError:
|
|
147
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
148
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
149
|
+
|
|
150
|
+
def data_filters(
|
|
151
|
+
self, id: int, *, request_options: typing.Optional[RequestOptions] = None
|
|
152
|
+
) -> StatsDataFiltersResponse:
|
|
153
|
+
"""
|
|
154
|
+
Get statistics about user data filters and their usage within a project.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
id : int
|
|
159
|
+
|
|
160
|
+
request_options : typing.Optional[RequestOptions]
|
|
161
|
+
Request-specific configuration.
|
|
162
|
+
|
|
163
|
+
Returns
|
|
164
|
+
-------
|
|
165
|
+
StatsDataFiltersResponse
|
|
166
|
+
User data filter statistics
|
|
167
|
+
|
|
168
|
+
Examples
|
|
169
|
+
--------
|
|
170
|
+
from label_studio_sdk import LabelStudio
|
|
171
|
+
|
|
172
|
+
client = LabelStudio(
|
|
173
|
+
api_key="YOUR_API_KEY",
|
|
174
|
+
)
|
|
175
|
+
client.projects.stats.data_filters(
|
|
176
|
+
id=1,
|
|
177
|
+
)
|
|
178
|
+
"""
|
|
179
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
180
|
+
f"api/projects/{jsonable_encoder(id)}/stats/data_filter",
|
|
181
|
+
method="GET",
|
|
182
|
+
request_options=request_options,
|
|
183
|
+
)
|
|
184
|
+
try:
|
|
185
|
+
if 200 <= _response.status_code < 300:
|
|
186
|
+
return typing.cast(
|
|
187
|
+
StatsDataFiltersResponse,
|
|
188
|
+
construct_type(
|
|
189
|
+
type_=StatsDataFiltersResponse, # type: ignore
|
|
190
|
+
object_=_response.json(),
|
|
191
|
+
),
|
|
192
|
+
)
|
|
193
|
+
_response_json = _response.json()
|
|
194
|
+
except JSONDecodeError:
|
|
195
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
196
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
197
|
+
|
|
198
|
+
def finished_tasks(
|
|
199
|
+
self, id: int, *, user_pk: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None
|
|
200
|
+
) -> StatsFinishedTasksResponse:
|
|
201
|
+
"""
|
|
202
|
+
Get statistics about finished tasks for a project.
|
|
203
|
+
|
|
204
|
+
Parameters
|
|
205
|
+
----------
|
|
206
|
+
id : int
|
|
207
|
+
|
|
208
|
+
user_pk : typing.Optional[int]
|
|
209
|
+
User ID to filter statistics by (optional)
|
|
210
|
+
|
|
211
|
+
request_options : typing.Optional[RequestOptions]
|
|
212
|
+
Request-specific configuration.
|
|
213
|
+
|
|
214
|
+
Returns
|
|
215
|
+
-------
|
|
216
|
+
StatsFinishedTasksResponse
|
|
217
|
+
Finished tasks statistics
|
|
218
|
+
|
|
219
|
+
Examples
|
|
220
|
+
--------
|
|
221
|
+
from label_studio_sdk import LabelStudio
|
|
222
|
+
|
|
223
|
+
client = LabelStudio(
|
|
224
|
+
api_key="YOUR_API_KEY",
|
|
225
|
+
)
|
|
226
|
+
client.projects.stats.finished_tasks(
|
|
227
|
+
id=1,
|
|
228
|
+
)
|
|
229
|
+
"""
|
|
230
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
231
|
+
f"api/projects/{jsonable_encoder(id)}/stats/finished",
|
|
232
|
+
method="GET",
|
|
233
|
+
params={
|
|
234
|
+
"user_pk": user_pk,
|
|
235
|
+
},
|
|
236
|
+
request_options=request_options,
|
|
237
|
+
)
|
|
238
|
+
try:
|
|
239
|
+
if 200 <= _response.status_code < 300:
|
|
240
|
+
return typing.cast(
|
|
241
|
+
StatsFinishedTasksResponse,
|
|
242
|
+
construct_type(
|
|
243
|
+
type_=StatsFinishedTasksResponse, # type: ignore
|
|
244
|
+
object_=_response.json(),
|
|
245
|
+
),
|
|
246
|
+
)
|
|
247
|
+
_response_json = _response.json()
|
|
248
|
+
except JSONDecodeError:
|
|
249
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
250
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
251
|
+
|
|
252
|
+
def lead_time(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> StatsLeadTimeResponse:
|
|
253
|
+
"""
|
|
254
|
+
Get lead time statistics across the project, including average annotation time.
|
|
255
|
+
|
|
256
|
+
Parameters
|
|
257
|
+
----------
|
|
258
|
+
id : int
|
|
259
|
+
|
|
260
|
+
request_options : typing.Optional[RequestOptions]
|
|
261
|
+
Request-specific configuration.
|
|
262
|
+
|
|
263
|
+
Returns
|
|
264
|
+
-------
|
|
265
|
+
StatsLeadTimeResponse
|
|
266
|
+
Lead time statistics
|
|
267
|
+
|
|
268
|
+
Examples
|
|
269
|
+
--------
|
|
270
|
+
from label_studio_sdk import LabelStudio
|
|
271
|
+
|
|
272
|
+
client = LabelStudio(
|
|
273
|
+
api_key="YOUR_API_KEY",
|
|
274
|
+
)
|
|
275
|
+
client.projects.stats.lead_time(
|
|
276
|
+
id=1,
|
|
277
|
+
)
|
|
278
|
+
"""
|
|
279
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
280
|
+
f"api/projects/{jsonable_encoder(id)}/stats/lead_time",
|
|
281
|
+
method="GET",
|
|
282
|
+
request_options=request_options,
|
|
283
|
+
)
|
|
284
|
+
try:
|
|
285
|
+
if 200 <= _response.status_code < 300:
|
|
286
|
+
return typing.cast(
|
|
287
|
+
StatsLeadTimeResponse,
|
|
288
|
+
construct_type(
|
|
289
|
+
type_=StatsLeadTimeResponse, # type: ignore
|
|
290
|
+
object_=_response.json(),
|
|
291
|
+
),
|
|
292
|
+
)
|
|
293
|
+
_response_json = _response.json()
|
|
294
|
+
except JSONDecodeError:
|
|
295
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
296
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
297
|
+
|
|
92
298
|
def total_agreement(
|
|
93
299
|
self,
|
|
94
300
|
id: int,
|
|
@@ -118,16 +324,647 @@ class StatsClient:
|
|
|
118
324
|
|
|
119
325
|
Examples
|
|
120
326
|
--------
|
|
121
|
-
from label_studio_sdk import LabelStudio
|
|
327
|
+
from label_studio_sdk import LabelStudio
|
|
328
|
+
|
|
329
|
+
client = LabelStudio(
|
|
330
|
+
api_key="YOUR_API_KEY",
|
|
331
|
+
)
|
|
332
|
+
client.projects.stats.total_agreement(
|
|
333
|
+
id=1,
|
|
334
|
+
)
|
|
335
|
+
"""
|
|
336
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
337
|
+
f"api/projects/{jsonable_encoder(id)}/stats/total_agreement",
|
|
338
|
+
method="GET",
|
|
339
|
+
params={
|
|
340
|
+
"per_label": per_label,
|
|
341
|
+
},
|
|
342
|
+
request_options=request_options,
|
|
343
|
+
)
|
|
344
|
+
try:
|
|
345
|
+
if 200 <= _response.status_code < 300:
|
|
346
|
+
return typing.cast(
|
|
347
|
+
StatsTotalAgreementResponse,
|
|
348
|
+
construct_type(
|
|
349
|
+
type_=StatsTotalAgreementResponse, # type: ignore
|
|
350
|
+
object_=_response.json(),
|
|
351
|
+
),
|
|
352
|
+
)
|
|
353
|
+
_response_json = _response.json()
|
|
354
|
+
except JSONDecodeError:
|
|
355
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
356
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
357
|
+
|
|
358
|
+
def update_stats(
|
|
359
|
+
self,
|
|
360
|
+
id: int,
|
|
361
|
+
*,
|
|
362
|
+
stat_type: typing.Optional[str] = None,
|
|
363
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
364
|
+
) -> typing.Dict[str, typing.Optional[typing.Any]]:
|
|
365
|
+
"""
|
|
366
|
+
Start stats recalculation for given project
|
|
367
|
+
|
|
368
|
+
Parameters
|
|
369
|
+
----------
|
|
370
|
+
id : int
|
|
371
|
+
|
|
372
|
+
stat_type : typing.Optional[str]
|
|
373
|
+
Stat type to recalculate. Possible values: label, stats
|
|
374
|
+
|
|
375
|
+
request_options : typing.Optional[RequestOptions]
|
|
376
|
+
Request-specific configuration.
|
|
377
|
+
|
|
378
|
+
Returns
|
|
379
|
+
-------
|
|
380
|
+
typing.Dict[str, typing.Optional[typing.Any]]
|
|
381
|
+
Successful response returns job id
|
|
382
|
+
|
|
383
|
+
Examples
|
|
384
|
+
--------
|
|
385
|
+
from label_studio_sdk import LabelStudio
|
|
386
|
+
|
|
387
|
+
client = LabelStudio(
|
|
388
|
+
api_key="YOUR_API_KEY",
|
|
389
|
+
)
|
|
390
|
+
client.projects.stats.update_stats(
|
|
391
|
+
id=1,
|
|
392
|
+
)
|
|
393
|
+
"""
|
|
394
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
395
|
+
f"api/projects/{jsonable_encoder(id)}/update-stats",
|
|
396
|
+
method="GET",
|
|
397
|
+
params={
|
|
398
|
+
"stat_type": stat_type,
|
|
399
|
+
},
|
|
400
|
+
request_options=request_options,
|
|
401
|
+
)
|
|
402
|
+
try:
|
|
403
|
+
if 200 <= _response.status_code < 300:
|
|
404
|
+
return typing.cast(
|
|
405
|
+
typing.Dict[str, typing.Optional[typing.Any]],
|
|
406
|
+
construct_type(
|
|
407
|
+
type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore
|
|
408
|
+
object_=_response.json(),
|
|
409
|
+
),
|
|
410
|
+
)
|
|
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
|
+
def user_prediction_agreement(
|
|
417
|
+
self,
|
|
418
|
+
id: int,
|
|
419
|
+
user_pk: int,
|
|
420
|
+
*,
|
|
421
|
+
per_label: typing.Optional[bool] = None,
|
|
422
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
423
|
+
) -> StatsUserPredictionAgreementResponse:
|
|
424
|
+
"""
|
|
425
|
+
Get prediction agreement statistics for a specific user within a project.
|
|
426
|
+
|
|
427
|
+
Parameters
|
|
428
|
+
----------
|
|
429
|
+
id : int
|
|
430
|
+
|
|
431
|
+
user_pk : int
|
|
432
|
+
|
|
433
|
+
per_label : typing.Optional[bool]
|
|
434
|
+
Calculate agreement per label
|
|
435
|
+
|
|
436
|
+
request_options : typing.Optional[RequestOptions]
|
|
437
|
+
Request-specific configuration.
|
|
438
|
+
|
|
439
|
+
Returns
|
|
440
|
+
-------
|
|
441
|
+
StatsUserPredictionAgreementResponse
|
|
442
|
+
Individual user prediction agreement statistics
|
|
443
|
+
|
|
444
|
+
Examples
|
|
445
|
+
--------
|
|
446
|
+
from label_studio_sdk import LabelStudio
|
|
447
|
+
|
|
448
|
+
client = LabelStudio(
|
|
449
|
+
api_key="YOUR_API_KEY",
|
|
450
|
+
)
|
|
451
|
+
client.projects.stats.user_prediction_agreement(
|
|
452
|
+
id=1,
|
|
453
|
+
user_pk=1,
|
|
454
|
+
)
|
|
455
|
+
"""
|
|
456
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
457
|
+
f"api/projects/{jsonable_encoder(id)}/user-stats/{jsonable_encoder(user_pk)}/prediction",
|
|
458
|
+
method="GET",
|
|
459
|
+
params={
|
|
460
|
+
"per_label": per_label,
|
|
461
|
+
},
|
|
462
|
+
request_options=request_options,
|
|
463
|
+
)
|
|
464
|
+
try:
|
|
465
|
+
if 200 <= _response.status_code < 300:
|
|
466
|
+
return typing.cast(
|
|
467
|
+
StatsUserPredictionAgreementResponse,
|
|
468
|
+
construct_type(
|
|
469
|
+
type_=StatsUserPredictionAgreementResponse, # type: ignore
|
|
470
|
+
object_=_response.json(),
|
|
471
|
+
),
|
|
472
|
+
)
|
|
473
|
+
_response_json = _response.json()
|
|
474
|
+
except JSONDecodeError:
|
|
475
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
476
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
477
|
+
|
|
478
|
+
def user_review_score(
|
|
479
|
+
self,
|
|
480
|
+
id: int,
|
|
481
|
+
user_pk: int,
|
|
482
|
+
*,
|
|
483
|
+
per_label: typing.Optional[bool] = None,
|
|
484
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
485
|
+
) -> StatsUserReviewScoreResponse:
|
|
486
|
+
"""
|
|
487
|
+
Get review score statistics for a specific user within a project.
|
|
488
|
+
|
|
489
|
+
Parameters
|
|
490
|
+
----------
|
|
491
|
+
id : int
|
|
492
|
+
|
|
493
|
+
user_pk : int
|
|
494
|
+
|
|
495
|
+
per_label : typing.Optional[bool]
|
|
496
|
+
Calculate agreement per label
|
|
497
|
+
|
|
498
|
+
request_options : typing.Optional[RequestOptions]
|
|
499
|
+
Request-specific configuration.
|
|
500
|
+
|
|
501
|
+
Returns
|
|
502
|
+
-------
|
|
503
|
+
StatsUserReviewScoreResponse
|
|
504
|
+
Individual user review score statistics
|
|
505
|
+
|
|
506
|
+
Examples
|
|
507
|
+
--------
|
|
508
|
+
from label_studio_sdk import LabelStudio
|
|
509
|
+
|
|
510
|
+
client = LabelStudio(
|
|
511
|
+
api_key="YOUR_API_KEY",
|
|
512
|
+
)
|
|
513
|
+
client.projects.stats.user_review_score(
|
|
514
|
+
id=1,
|
|
515
|
+
user_pk=1,
|
|
516
|
+
)
|
|
517
|
+
"""
|
|
518
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
519
|
+
f"api/projects/{jsonable_encoder(id)}/user-stats/{jsonable_encoder(user_pk)}/review_score",
|
|
520
|
+
method="GET",
|
|
521
|
+
params={
|
|
522
|
+
"per_label": per_label,
|
|
523
|
+
},
|
|
524
|
+
request_options=request_options,
|
|
525
|
+
)
|
|
526
|
+
try:
|
|
527
|
+
if 200 <= _response.status_code < 300:
|
|
528
|
+
return typing.cast(
|
|
529
|
+
StatsUserReviewScoreResponse,
|
|
530
|
+
construct_type(
|
|
531
|
+
type_=StatsUserReviewScoreResponse, # type: ignore
|
|
532
|
+
object_=_response.json(),
|
|
533
|
+
),
|
|
534
|
+
)
|
|
535
|
+
_response_json = _response.json()
|
|
536
|
+
except JSONDecodeError:
|
|
537
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
538
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
539
|
+
|
|
540
|
+
def user_ground_truth_agreement(
|
|
541
|
+
self,
|
|
542
|
+
id: int,
|
|
543
|
+
user_pk: int,
|
|
544
|
+
*,
|
|
545
|
+
per_label: typing.Optional[bool] = None,
|
|
546
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
547
|
+
) -> StatsUserGroundTruthAgreementResponse:
|
|
548
|
+
"""
|
|
549
|
+
Get ground truth agreement statistics for a specific user within a project.
|
|
550
|
+
|
|
551
|
+
Parameters
|
|
552
|
+
----------
|
|
553
|
+
id : int
|
|
554
|
+
|
|
555
|
+
user_pk : int
|
|
556
|
+
|
|
557
|
+
per_label : typing.Optional[bool]
|
|
558
|
+
Calculate agreement per label
|
|
559
|
+
|
|
560
|
+
request_options : typing.Optional[RequestOptions]
|
|
561
|
+
Request-specific configuration.
|
|
562
|
+
|
|
563
|
+
Returns
|
|
564
|
+
-------
|
|
565
|
+
StatsUserGroundTruthAgreementResponse
|
|
566
|
+
Individual user ground truth agreement statistics
|
|
567
|
+
|
|
568
|
+
Examples
|
|
569
|
+
--------
|
|
570
|
+
from label_studio_sdk import LabelStudio
|
|
571
|
+
|
|
572
|
+
client = LabelStudio(
|
|
573
|
+
api_key="YOUR_API_KEY",
|
|
574
|
+
)
|
|
575
|
+
client.projects.stats.user_ground_truth_agreement(
|
|
576
|
+
id=1,
|
|
577
|
+
user_pk=1,
|
|
578
|
+
)
|
|
579
|
+
"""
|
|
580
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
581
|
+
f"api/projects/{jsonable_encoder(id)}/users/{jsonable_encoder(user_pk)}/stats/agreement-groundtruth",
|
|
582
|
+
method="GET",
|
|
583
|
+
params={
|
|
584
|
+
"per_label": per_label,
|
|
585
|
+
},
|
|
586
|
+
request_options=request_options,
|
|
587
|
+
)
|
|
588
|
+
try:
|
|
589
|
+
if 200 <= _response.status_code < 300:
|
|
590
|
+
return typing.cast(
|
|
591
|
+
StatsUserGroundTruthAgreementResponse,
|
|
592
|
+
construct_type(
|
|
593
|
+
type_=StatsUserGroundTruthAgreementResponse, # type: ignore
|
|
594
|
+
object_=_response.json(),
|
|
595
|
+
),
|
|
596
|
+
)
|
|
597
|
+
_response_json = _response.json()
|
|
598
|
+
except JSONDecodeError:
|
|
599
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
600
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
class AsyncStatsClient:
|
|
604
|
+
def __init__(self, *, client_wrapper: AsyncClientWrapper):
|
|
605
|
+
self._client_wrapper = client_wrapper
|
|
606
|
+
|
|
607
|
+
async def iaa(
|
|
608
|
+
self,
|
|
609
|
+
id: int,
|
|
610
|
+
*,
|
|
611
|
+
expand: typing.Optional[str] = None,
|
|
612
|
+
per_label: typing.Optional[bool] = None,
|
|
613
|
+
std: typing.Optional[bool] = None,
|
|
614
|
+
task: typing.Optional[str] = None,
|
|
615
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
616
|
+
) -> StatsIaaResponse:
|
|
617
|
+
"""
|
|
618
|
+
Get Inter-Annotator Agreement (IAA) matrix for a project, showing agreement between all annotators.
|
|
619
|
+
|
|
620
|
+
Parameters
|
|
621
|
+
----------
|
|
622
|
+
id : int
|
|
623
|
+
|
|
624
|
+
expand : typing.Optional[str]
|
|
625
|
+
Comma-separated list of fields to expand
|
|
626
|
+
|
|
627
|
+
per_label : typing.Optional[bool]
|
|
628
|
+
Calculate IAA per label
|
|
629
|
+
|
|
630
|
+
std : typing.Optional[bool]
|
|
631
|
+
Include standard deviation in results
|
|
632
|
+
|
|
633
|
+
task : typing.Optional[str]
|
|
634
|
+
Comma-separated list of task IDs to filter by
|
|
635
|
+
|
|
636
|
+
request_options : typing.Optional[RequestOptions]
|
|
637
|
+
Request-specific configuration.
|
|
638
|
+
|
|
639
|
+
Returns
|
|
640
|
+
-------
|
|
641
|
+
StatsIaaResponse
|
|
642
|
+
Inter-Annotator Agreement matrix
|
|
643
|
+
|
|
644
|
+
Examples
|
|
645
|
+
--------
|
|
646
|
+
import asyncio
|
|
647
|
+
|
|
648
|
+
from label_studio_sdk import AsyncLabelStudio
|
|
649
|
+
|
|
650
|
+
client = AsyncLabelStudio(
|
|
651
|
+
api_key="YOUR_API_KEY",
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
async def main() -> None:
|
|
656
|
+
await client.projects.stats.iaa(
|
|
657
|
+
id=1,
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
asyncio.run(main())
|
|
662
|
+
"""
|
|
663
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
664
|
+
f"api/projects/{jsonable_encoder(id)}/stats/IAA",
|
|
665
|
+
method="GET",
|
|
666
|
+
params={
|
|
667
|
+
"expand": expand,
|
|
668
|
+
"per_label": per_label,
|
|
669
|
+
"std": std,
|
|
670
|
+
"task": task,
|
|
671
|
+
},
|
|
672
|
+
request_options=request_options,
|
|
673
|
+
)
|
|
674
|
+
try:
|
|
675
|
+
if 200 <= _response.status_code < 300:
|
|
676
|
+
return typing.cast(
|
|
677
|
+
StatsIaaResponse,
|
|
678
|
+
construct_type(
|
|
679
|
+
type_=StatsIaaResponse, # type: ignore
|
|
680
|
+
object_=_response.json(),
|
|
681
|
+
),
|
|
682
|
+
)
|
|
683
|
+
_response_json = _response.json()
|
|
684
|
+
except JSONDecodeError:
|
|
685
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
686
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
687
|
+
|
|
688
|
+
async def agreement_annotator(
|
|
689
|
+
self, id: int, user_id: int, *, request_options: typing.Optional[RequestOptions] = None
|
|
690
|
+
) -> StatsAgreementAnnotatorResponse:
|
|
691
|
+
"""
|
|
692
|
+
Get agreement statistics for a specific annotator within a project.
|
|
693
|
+
|
|
694
|
+
Parameters
|
|
695
|
+
----------
|
|
696
|
+
id : int
|
|
697
|
+
|
|
698
|
+
user_id : int
|
|
699
|
+
|
|
700
|
+
request_options : typing.Optional[RequestOptions]
|
|
701
|
+
Request-specific configuration.
|
|
702
|
+
|
|
703
|
+
Returns
|
|
704
|
+
-------
|
|
705
|
+
StatsAgreementAnnotatorResponse
|
|
706
|
+
Individual annotator agreement statistics
|
|
707
|
+
|
|
708
|
+
Examples
|
|
709
|
+
--------
|
|
710
|
+
import asyncio
|
|
711
|
+
|
|
712
|
+
from label_studio_sdk import AsyncLabelStudio
|
|
713
|
+
|
|
714
|
+
client = AsyncLabelStudio(
|
|
715
|
+
api_key="YOUR_API_KEY",
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
async def main() -> None:
|
|
720
|
+
await client.projects.stats.agreement_annotator(
|
|
721
|
+
id=1,
|
|
722
|
+
user_id=1,
|
|
723
|
+
)
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
asyncio.run(main())
|
|
727
|
+
"""
|
|
728
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
729
|
+
f"api/projects/{jsonable_encoder(id)}/stats/agreement_annotator/{jsonable_encoder(user_id)}",
|
|
730
|
+
method="GET",
|
|
731
|
+
request_options=request_options,
|
|
732
|
+
)
|
|
733
|
+
try:
|
|
734
|
+
if 200 <= _response.status_code < 300:
|
|
735
|
+
return typing.cast(
|
|
736
|
+
StatsAgreementAnnotatorResponse,
|
|
737
|
+
construct_type(
|
|
738
|
+
type_=StatsAgreementAnnotatorResponse, # type: ignore
|
|
739
|
+
object_=_response.json(),
|
|
740
|
+
),
|
|
741
|
+
)
|
|
742
|
+
_response_json = _response.json()
|
|
743
|
+
except JSONDecodeError:
|
|
744
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
745
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
746
|
+
|
|
747
|
+
async def data_filters(
|
|
748
|
+
self, id: int, *, request_options: typing.Optional[RequestOptions] = None
|
|
749
|
+
) -> StatsDataFiltersResponse:
|
|
750
|
+
"""
|
|
751
|
+
Get statistics about user data filters and their usage within a project.
|
|
752
|
+
|
|
753
|
+
Parameters
|
|
754
|
+
----------
|
|
755
|
+
id : int
|
|
756
|
+
|
|
757
|
+
request_options : typing.Optional[RequestOptions]
|
|
758
|
+
Request-specific configuration.
|
|
759
|
+
|
|
760
|
+
Returns
|
|
761
|
+
-------
|
|
762
|
+
StatsDataFiltersResponse
|
|
763
|
+
User data filter statistics
|
|
764
|
+
|
|
765
|
+
Examples
|
|
766
|
+
--------
|
|
767
|
+
import asyncio
|
|
768
|
+
|
|
769
|
+
from label_studio_sdk import AsyncLabelStudio
|
|
770
|
+
|
|
771
|
+
client = AsyncLabelStudio(
|
|
772
|
+
api_key="YOUR_API_KEY",
|
|
773
|
+
)
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
async def main() -> None:
|
|
777
|
+
await client.projects.stats.data_filters(
|
|
778
|
+
id=1,
|
|
779
|
+
)
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
asyncio.run(main())
|
|
783
|
+
"""
|
|
784
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
785
|
+
f"api/projects/{jsonable_encoder(id)}/stats/data_filter",
|
|
786
|
+
method="GET",
|
|
787
|
+
request_options=request_options,
|
|
788
|
+
)
|
|
789
|
+
try:
|
|
790
|
+
if 200 <= _response.status_code < 300:
|
|
791
|
+
return typing.cast(
|
|
792
|
+
StatsDataFiltersResponse,
|
|
793
|
+
construct_type(
|
|
794
|
+
type_=StatsDataFiltersResponse, # type: ignore
|
|
795
|
+
object_=_response.json(),
|
|
796
|
+
),
|
|
797
|
+
)
|
|
798
|
+
_response_json = _response.json()
|
|
799
|
+
except JSONDecodeError:
|
|
800
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
801
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
802
|
+
|
|
803
|
+
async def finished_tasks(
|
|
804
|
+
self, id: int, *, user_pk: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None
|
|
805
|
+
) -> StatsFinishedTasksResponse:
|
|
806
|
+
"""
|
|
807
|
+
Get statistics about finished tasks for a project.
|
|
808
|
+
|
|
809
|
+
Parameters
|
|
810
|
+
----------
|
|
811
|
+
id : int
|
|
812
|
+
|
|
813
|
+
user_pk : typing.Optional[int]
|
|
814
|
+
User ID to filter statistics by (optional)
|
|
815
|
+
|
|
816
|
+
request_options : typing.Optional[RequestOptions]
|
|
817
|
+
Request-specific configuration.
|
|
818
|
+
|
|
819
|
+
Returns
|
|
820
|
+
-------
|
|
821
|
+
StatsFinishedTasksResponse
|
|
822
|
+
Finished tasks statistics
|
|
823
|
+
|
|
824
|
+
Examples
|
|
825
|
+
--------
|
|
826
|
+
import asyncio
|
|
827
|
+
|
|
828
|
+
from label_studio_sdk import AsyncLabelStudio
|
|
829
|
+
|
|
830
|
+
client = AsyncLabelStudio(
|
|
831
|
+
api_key="YOUR_API_KEY",
|
|
832
|
+
)
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
async def main() -> None:
|
|
836
|
+
await client.projects.stats.finished_tasks(
|
|
837
|
+
id=1,
|
|
838
|
+
)
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
asyncio.run(main())
|
|
842
|
+
"""
|
|
843
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
844
|
+
f"api/projects/{jsonable_encoder(id)}/stats/finished",
|
|
845
|
+
method="GET",
|
|
846
|
+
params={
|
|
847
|
+
"user_pk": user_pk,
|
|
848
|
+
},
|
|
849
|
+
request_options=request_options,
|
|
850
|
+
)
|
|
851
|
+
try:
|
|
852
|
+
if 200 <= _response.status_code < 300:
|
|
853
|
+
return typing.cast(
|
|
854
|
+
StatsFinishedTasksResponse,
|
|
855
|
+
construct_type(
|
|
856
|
+
type_=StatsFinishedTasksResponse, # type: ignore
|
|
857
|
+
object_=_response.json(),
|
|
858
|
+
),
|
|
859
|
+
)
|
|
860
|
+
_response_json = _response.json()
|
|
861
|
+
except JSONDecodeError:
|
|
862
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
863
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
864
|
+
|
|
865
|
+
async def lead_time(
|
|
866
|
+
self, id: int, *, request_options: typing.Optional[RequestOptions] = None
|
|
867
|
+
) -> StatsLeadTimeResponse:
|
|
868
|
+
"""
|
|
869
|
+
Get lead time statistics across the project, including average annotation time.
|
|
870
|
+
|
|
871
|
+
Parameters
|
|
872
|
+
----------
|
|
873
|
+
id : int
|
|
874
|
+
|
|
875
|
+
request_options : typing.Optional[RequestOptions]
|
|
876
|
+
Request-specific configuration.
|
|
877
|
+
|
|
878
|
+
Returns
|
|
879
|
+
-------
|
|
880
|
+
StatsLeadTimeResponse
|
|
881
|
+
Lead time statistics
|
|
882
|
+
|
|
883
|
+
Examples
|
|
884
|
+
--------
|
|
885
|
+
import asyncio
|
|
886
|
+
|
|
887
|
+
from label_studio_sdk import AsyncLabelStudio
|
|
888
|
+
|
|
889
|
+
client = AsyncLabelStudio(
|
|
890
|
+
api_key="YOUR_API_KEY",
|
|
891
|
+
)
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
async def main() -> None:
|
|
895
|
+
await client.projects.stats.lead_time(
|
|
896
|
+
id=1,
|
|
897
|
+
)
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
asyncio.run(main())
|
|
901
|
+
"""
|
|
902
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
903
|
+
f"api/projects/{jsonable_encoder(id)}/stats/lead_time",
|
|
904
|
+
method="GET",
|
|
905
|
+
request_options=request_options,
|
|
906
|
+
)
|
|
907
|
+
try:
|
|
908
|
+
if 200 <= _response.status_code < 300:
|
|
909
|
+
return typing.cast(
|
|
910
|
+
StatsLeadTimeResponse,
|
|
911
|
+
construct_type(
|
|
912
|
+
type_=StatsLeadTimeResponse, # type: ignore
|
|
913
|
+
object_=_response.json(),
|
|
914
|
+
),
|
|
915
|
+
)
|
|
916
|
+
_response_json = _response.json()
|
|
917
|
+
except JSONDecodeError:
|
|
918
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
919
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
920
|
+
|
|
921
|
+
async def total_agreement(
|
|
922
|
+
self,
|
|
923
|
+
id: int,
|
|
924
|
+
*,
|
|
925
|
+
per_label: typing.Optional[bool] = None,
|
|
926
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
927
|
+
) -> StatsTotalAgreementResponse:
|
|
928
|
+
"""
|
|
929
|
+
Overall or per-label total agreement across the project.
|
|
930
|
+
|
|
931
|
+
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.
|
|
932
|
+
|
|
933
|
+
Parameters
|
|
934
|
+
----------
|
|
935
|
+
id : int
|
|
936
|
+
|
|
937
|
+
per_label : typing.Optional[bool]
|
|
938
|
+
Return agreement per label
|
|
939
|
+
|
|
940
|
+
request_options : typing.Optional[RequestOptions]
|
|
941
|
+
Request-specific configuration.
|
|
942
|
+
|
|
943
|
+
Returns
|
|
944
|
+
-------
|
|
945
|
+
StatsTotalAgreementResponse
|
|
946
|
+
Total agreement
|
|
947
|
+
|
|
948
|
+
Examples
|
|
949
|
+
--------
|
|
950
|
+
import asyncio
|
|
122
951
|
|
|
123
|
-
|
|
952
|
+
from label_studio_sdk import AsyncLabelStudio
|
|
953
|
+
|
|
954
|
+
client = AsyncLabelStudio(
|
|
124
955
|
api_key="YOUR_API_KEY",
|
|
125
956
|
)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
)
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
async def main() -> None:
|
|
960
|
+
await client.projects.stats.total_agreement(
|
|
961
|
+
id=1,
|
|
962
|
+
)
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
asyncio.run(main())
|
|
129
966
|
"""
|
|
130
|
-
_response = self._client_wrapper.httpx_client.request(
|
|
967
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
131
968
|
f"api/projects/{jsonable_encoder(id)}/stats/total_agreement",
|
|
132
969
|
method="GET",
|
|
133
970
|
params={
|
|
@@ -149,47 +986,169 @@ class StatsClient:
|
|
|
149
986
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
150
987
|
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
151
988
|
|
|
989
|
+
async def update_stats(
|
|
990
|
+
self,
|
|
991
|
+
id: int,
|
|
992
|
+
*,
|
|
993
|
+
stat_type: typing.Optional[str] = None,
|
|
994
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
995
|
+
) -> typing.Dict[str, typing.Optional[typing.Any]]:
|
|
996
|
+
"""
|
|
997
|
+
Start stats recalculation for given project
|
|
152
998
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
999
|
+
Parameters
|
|
1000
|
+
----------
|
|
1001
|
+
id : int
|
|
156
1002
|
|
|
157
|
-
|
|
1003
|
+
stat_type : typing.Optional[str]
|
|
1004
|
+
Stat type to recalculate. Possible values: label, stats
|
|
1005
|
+
|
|
1006
|
+
request_options : typing.Optional[RequestOptions]
|
|
1007
|
+
Request-specific configuration.
|
|
1008
|
+
|
|
1009
|
+
Returns
|
|
1010
|
+
-------
|
|
1011
|
+
typing.Dict[str, typing.Optional[typing.Any]]
|
|
1012
|
+
Successful response returns job id
|
|
1013
|
+
|
|
1014
|
+
Examples
|
|
1015
|
+
--------
|
|
1016
|
+
import asyncio
|
|
1017
|
+
|
|
1018
|
+
from label_studio_sdk import AsyncLabelStudio
|
|
1019
|
+
|
|
1020
|
+
client = AsyncLabelStudio(
|
|
1021
|
+
api_key="YOUR_API_KEY",
|
|
1022
|
+
)
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
async def main() -> None:
|
|
1026
|
+
await client.projects.stats.update_stats(
|
|
1027
|
+
id=1,
|
|
1028
|
+
)
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
asyncio.run(main())
|
|
1032
|
+
"""
|
|
1033
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1034
|
+
f"api/projects/{jsonable_encoder(id)}/update-stats",
|
|
1035
|
+
method="GET",
|
|
1036
|
+
params={
|
|
1037
|
+
"stat_type": stat_type,
|
|
1038
|
+
},
|
|
1039
|
+
request_options=request_options,
|
|
1040
|
+
)
|
|
1041
|
+
try:
|
|
1042
|
+
if 200 <= _response.status_code < 300:
|
|
1043
|
+
return typing.cast(
|
|
1044
|
+
typing.Dict[str, typing.Optional[typing.Any]],
|
|
1045
|
+
construct_type(
|
|
1046
|
+
type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore
|
|
1047
|
+
object_=_response.json(),
|
|
1048
|
+
),
|
|
1049
|
+
)
|
|
1050
|
+
_response_json = _response.json()
|
|
1051
|
+
except JSONDecodeError:
|
|
1052
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
1053
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
1054
|
+
|
|
1055
|
+
async def user_prediction_agreement(
|
|
158
1056
|
self,
|
|
159
1057
|
id: int,
|
|
1058
|
+
user_pk: int,
|
|
160
1059
|
*,
|
|
161
|
-
expand: typing.Optional[str] = None,
|
|
162
1060
|
per_label: typing.Optional[bool] = None,
|
|
163
|
-
std: typing.Optional[bool] = None,
|
|
164
|
-
task: typing.Optional[str] = None,
|
|
165
1061
|
request_options: typing.Optional[RequestOptions] = None,
|
|
166
|
-
) ->
|
|
1062
|
+
) -> StatsUserPredictionAgreementResponse:
|
|
167
1063
|
"""
|
|
168
|
-
Get
|
|
1064
|
+
Get prediction agreement statistics for a specific user within a project.
|
|
169
1065
|
|
|
170
1066
|
Parameters
|
|
171
1067
|
----------
|
|
172
1068
|
id : int
|
|
173
1069
|
|
|
174
|
-
|
|
175
|
-
Comma-separated list of fields to expand
|
|
1070
|
+
user_pk : int
|
|
176
1071
|
|
|
177
1072
|
per_label : typing.Optional[bool]
|
|
178
|
-
Calculate
|
|
1073
|
+
Calculate agreement per label
|
|
179
1074
|
|
|
180
|
-
|
|
181
|
-
|
|
1075
|
+
request_options : typing.Optional[RequestOptions]
|
|
1076
|
+
Request-specific configuration.
|
|
182
1077
|
|
|
183
|
-
|
|
184
|
-
|
|
1078
|
+
Returns
|
|
1079
|
+
-------
|
|
1080
|
+
StatsUserPredictionAgreementResponse
|
|
1081
|
+
Individual user prediction agreement statistics
|
|
1082
|
+
|
|
1083
|
+
Examples
|
|
1084
|
+
--------
|
|
1085
|
+
import asyncio
|
|
1086
|
+
|
|
1087
|
+
from label_studio_sdk import AsyncLabelStudio
|
|
1088
|
+
|
|
1089
|
+
client = AsyncLabelStudio(
|
|
1090
|
+
api_key="YOUR_API_KEY",
|
|
1091
|
+
)
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
async def main() -> None:
|
|
1095
|
+
await client.projects.stats.user_prediction_agreement(
|
|
1096
|
+
id=1,
|
|
1097
|
+
user_pk=1,
|
|
1098
|
+
)
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
asyncio.run(main())
|
|
1102
|
+
"""
|
|
1103
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1104
|
+
f"api/projects/{jsonable_encoder(id)}/user-stats/{jsonable_encoder(user_pk)}/prediction",
|
|
1105
|
+
method="GET",
|
|
1106
|
+
params={
|
|
1107
|
+
"per_label": per_label,
|
|
1108
|
+
},
|
|
1109
|
+
request_options=request_options,
|
|
1110
|
+
)
|
|
1111
|
+
try:
|
|
1112
|
+
if 200 <= _response.status_code < 300:
|
|
1113
|
+
return typing.cast(
|
|
1114
|
+
StatsUserPredictionAgreementResponse,
|
|
1115
|
+
construct_type(
|
|
1116
|
+
type_=StatsUserPredictionAgreementResponse, # type: ignore
|
|
1117
|
+
object_=_response.json(),
|
|
1118
|
+
),
|
|
1119
|
+
)
|
|
1120
|
+
_response_json = _response.json()
|
|
1121
|
+
except JSONDecodeError:
|
|
1122
|
+
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
1123
|
+
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
1124
|
+
|
|
1125
|
+
async def user_review_score(
|
|
1126
|
+
self,
|
|
1127
|
+
id: int,
|
|
1128
|
+
user_pk: int,
|
|
1129
|
+
*,
|
|
1130
|
+
per_label: typing.Optional[bool] = None,
|
|
1131
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
1132
|
+
) -> StatsUserReviewScoreResponse:
|
|
1133
|
+
"""
|
|
1134
|
+
Get review score statistics for a specific user within a project.
|
|
1135
|
+
|
|
1136
|
+
Parameters
|
|
1137
|
+
----------
|
|
1138
|
+
id : int
|
|
1139
|
+
|
|
1140
|
+
user_pk : int
|
|
1141
|
+
|
|
1142
|
+
per_label : typing.Optional[bool]
|
|
1143
|
+
Calculate agreement per label
|
|
185
1144
|
|
|
186
1145
|
request_options : typing.Optional[RequestOptions]
|
|
187
1146
|
Request-specific configuration.
|
|
188
1147
|
|
|
189
1148
|
Returns
|
|
190
1149
|
-------
|
|
191
|
-
|
|
192
|
-
|
|
1150
|
+
StatsUserReviewScoreResponse
|
|
1151
|
+
Individual user review score statistics
|
|
193
1152
|
|
|
194
1153
|
Examples
|
|
195
1154
|
--------
|
|
@@ -203,30 +1162,28 @@ class AsyncStatsClient:
|
|
|
203
1162
|
|
|
204
1163
|
|
|
205
1164
|
async def main() -> None:
|
|
206
|
-
await client.projects.stats.
|
|
1165
|
+
await client.projects.stats.user_review_score(
|
|
207
1166
|
id=1,
|
|
1167
|
+
user_pk=1,
|
|
208
1168
|
)
|
|
209
1169
|
|
|
210
1170
|
|
|
211
1171
|
asyncio.run(main())
|
|
212
1172
|
"""
|
|
213
1173
|
_response = await self._client_wrapper.httpx_client.request(
|
|
214
|
-
f"api/projects/{jsonable_encoder(id)}/stats/
|
|
1174
|
+
f"api/projects/{jsonable_encoder(id)}/user-stats/{jsonable_encoder(user_pk)}/review_score",
|
|
215
1175
|
method="GET",
|
|
216
1176
|
params={
|
|
217
|
-
"expand": expand,
|
|
218
1177
|
"per_label": per_label,
|
|
219
|
-
"std": std,
|
|
220
|
-
"task": task,
|
|
221
1178
|
},
|
|
222
1179
|
request_options=request_options,
|
|
223
1180
|
)
|
|
224
1181
|
try:
|
|
225
1182
|
if 200 <= _response.status_code < 300:
|
|
226
1183
|
return typing.cast(
|
|
227
|
-
|
|
1184
|
+
StatsUserReviewScoreResponse,
|
|
228
1185
|
construct_type(
|
|
229
|
-
type_=
|
|
1186
|
+
type_=StatsUserReviewScoreResponse, # type: ignore
|
|
230
1187
|
object_=_response.json(),
|
|
231
1188
|
),
|
|
232
1189
|
)
|
|
@@ -235,32 +1192,33 @@ class AsyncStatsClient:
|
|
|
235
1192
|
raise ApiError(status_code=_response.status_code, body=_response.text)
|
|
236
1193
|
raise ApiError(status_code=_response.status_code, body=_response_json)
|
|
237
1194
|
|
|
238
|
-
async def
|
|
1195
|
+
async def user_ground_truth_agreement(
|
|
239
1196
|
self,
|
|
240
1197
|
id: int,
|
|
1198
|
+
user_pk: int,
|
|
241
1199
|
*,
|
|
242
1200
|
per_label: typing.Optional[bool] = None,
|
|
243
1201
|
request_options: typing.Optional[RequestOptions] = None,
|
|
244
|
-
) ->
|
|
1202
|
+
) -> StatsUserGroundTruthAgreementResponse:
|
|
245
1203
|
"""
|
|
246
|
-
|
|
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.
|
|
1204
|
+
Get ground truth agreement statistics for a specific user within a project.
|
|
249
1205
|
|
|
250
1206
|
Parameters
|
|
251
1207
|
----------
|
|
252
1208
|
id : int
|
|
253
1209
|
|
|
1210
|
+
user_pk : int
|
|
1211
|
+
|
|
254
1212
|
per_label : typing.Optional[bool]
|
|
255
|
-
|
|
1213
|
+
Calculate agreement per label
|
|
256
1214
|
|
|
257
1215
|
request_options : typing.Optional[RequestOptions]
|
|
258
1216
|
Request-specific configuration.
|
|
259
1217
|
|
|
260
1218
|
Returns
|
|
261
1219
|
-------
|
|
262
|
-
|
|
263
|
-
|
|
1220
|
+
StatsUserGroundTruthAgreementResponse
|
|
1221
|
+
Individual user ground truth agreement statistics
|
|
264
1222
|
|
|
265
1223
|
Examples
|
|
266
1224
|
--------
|
|
@@ -274,15 +1232,16 @@ class AsyncStatsClient:
|
|
|
274
1232
|
|
|
275
1233
|
|
|
276
1234
|
async def main() -> None:
|
|
277
|
-
await client.projects.stats.
|
|
1235
|
+
await client.projects.stats.user_ground_truth_agreement(
|
|
278
1236
|
id=1,
|
|
1237
|
+
user_pk=1,
|
|
279
1238
|
)
|
|
280
1239
|
|
|
281
1240
|
|
|
282
1241
|
asyncio.run(main())
|
|
283
1242
|
"""
|
|
284
1243
|
_response = await self._client_wrapper.httpx_client.request(
|
|
285
|
-
f"api/projects/{jsonable_encoder(id)}/stats/
|
|
1244
|
+
f"api/projects/{jsonable_encoder(id)}/users/{jsonable_encoder(user_pk)}/stats/agreement-groundtruth",
|
|
286
1245
|
method="GET",
|
|
287
1246
|
params={
|
|
288
1247
|
"per_label": per_label,
|
|
@@ -292,9 +1251,9 @@ class AsyncStatsClient:
|
|
|
292
1251
|
try:
|
|
293
1252
|
if 200 <= _response.status_code < 300:
|
|
294
1253
|
return typing.cast(
|
|
295
|
-
|
|
1254
|
+
StatsUserGroundTruthAgreementResponse,
|
|
296
1255
|
construct_type(
|
|
297
|
-
type_=
|
|
1256
|
+
type_=StatsUserGroundTruthAgreementResponse, # type: ignore
|
|
298
1257
|
object_=_response.json(),
|
|
299
1258
|
),
|
|
300
1259
|
)
|