rapidata 2.35.0__py3-none-any.whl → 2.35.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rapidata might be problematic. Click here for more details.
- rapidata/__init__.py +1 -1
- rapidata/api_client/api/leaderboard_api.py +3 -3
- rapidata/api_client_README.md +1 -1
- rapidata/rapidata_client/api/rapidata_exception.py +61 -32
- rapidata/rapidata_client/benchmark/_detail_mapper.py +0 -2
- rapidata/rapidata_client/benchmark/leaderboard/rapidata_leaderboard.py +33 -1
- rapidata/rapidata_client/benchmark/rapidata_benchmark.py +11 -1
- rapidata/rapidata_client/datapoints/assets/_multi_asset.py +7 -7
- rapidata/rapidata_client/order/_rapidata_dataset.py +158 -97
- rapidata/rapidata_client/order/_rapidata_order_builder.py +54 -22
- rapidata/rapidata_client/order/rapidata_order.py +109 -48
- rapidata/rapidata_client/rapidata_client.py +19 -14
- rapidata/rapidata_client/validation/rapidata_validation_set.py +13 -7
- rapidata/rapidata_client/validation/validation_set_manager.py +167 -98
- rapidata/service/credential_manager.py +13 -13
- rapidata/service/openapi_service.py +22 -13
- {rapidata-2.35.0.dist-info → rapidata-2.35.2.dist-info}/METADATA +1 -1
- {rapidata-2.35.0.dist-info → rapidata-2.35.2.dist-info}/RECORD +20 -20
- {rapidata-2.35.0.dist-info → rapidata-2.35.2.dist-info}/LICENSE +0 -0
- {rapidata-2.35.0.dist-info → rapidata-2.35.2.dist-info}/WHEEL +0 -0
rapidata/__init__.py
CHANGED
|
@@ -3117,7 +3117,7 @@ class LeaderboardApi:
|
|
|
3117
3117
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
3118
3118
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
3119
3119
|
) -> None:
|
|
3120
|
-
"""Updates the
|
|
3120
|
+
"""Updates the response config of a leaderboard.
|
|
3121
3121
|
|
|
3122
3122
|
|
|
3123
3123
|
:param leaderboard_id: (required)
|
|
@@ -3187,7 +3187,7 @@ class LeaderboardApi:
|
|
|
3187
3187
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
3188
3188
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
3189
3189
|
) -> ApiResponse[None]:
|
|
3190
|
-
"""Updates the
|
|
3190
|
+
"""Updates the response config of a leaderboard.
|
|
3191
3191
|
|
|
3192
3192
|
|
|
3193
3193
|
:param leaderboard_id: (required)
|
|
@@ -3257,7 +3257,7 @@ class LeaderboardApi:
|
|
|
3257
3257
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
3258
3258
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
3259
3259
|
) -> RESTResponseType:
|
|
3260
|
-
"""Updates the
|
|
3260
|
+
"""Updates the response config of a leaderboard.
|
|
3261
3261
|
|
|
3262
3262
|
|
|
3263
3263
|
:param leaderboard_id: (required)
|
rapidata/api_client_README.md
CHANGED
|
@@ -135,7 +135,7 @@ Class | Method | HTTP request | Description
|
|
|
135
135
|
*LeaderboardApi* | [**leaderboard_leaderboard_id_participants_post**](rapidata/api_client/docs/LeaderboardApi.md#leaderboard_leaderboard_id_participants_post) | **POST** /leaderboard/{leaderboardId}/participants | Creates a participant in a leaderboard.
|
|
136
136
|
*LeaderboardApi* | [**leaderboard_leaderboard_id_prompts_get**](rapidata/api_client/docs/LeaderboardApi.md#leaderboard_leaderboard_id_prompts_get) | **GET** /leaderboard/{leaderboardId}/prompts | returns the paged prompts of a leaderboard by its ID.
|
|
137
137
|
*LeaderboardApi* | [**leaderboard_leaderboard_id_prompts_post**](rapidata/api_client/docs/LeaderboardApi.md#leaderboard_leaderboard_id_prompts_post) | **POST** /leaderboard/{leaderboardId}/prompts | adds a new prompt to a leaderboard.
|
|
138
|
-
*LeaderboardApi* | [**leaderboard_leaderboard_id_response_config_put**](rapidata/api_client/docs/LeaderboardApi.md#leaderboard_leaderboard_id_response_config_put) | **PUT** /leaderboard/{leaderboardId}/response-config | Updates the
|
|
138
|
+
*LeaderboardApi* | [**leaderboard_leaderboard_id_response_config_put**](rapidata/api_client/docs/LeaderboardApi.md#leaderboard_leaderboard_id_response_config_put) | **PUT** /leaderboard/{leaderboardId}/response-config | Updates the response config of a leaderboard.
|
|
139
139
|
*LeaderboardApi* | [**leaderboard_leaderboard_id_runs_get**](rapidata/api_client/docs/LeaderboardApi.md#leaderboard_leaderboard_id_runs_get) | **GET** /leaderboard/{leaderboardId}/runs | Gets the runs related to a leaderboard
|
|
140
140
|
*LeaderboardApi* | [**leaderboard_leaderboard_id_standings_get**](rapidata/api_client/docs/LeaderboardApi.md#leaderboard_leaderboard_id_standings_get) | **GET** /leaderboard/{leaderboardId}/standings | queries all the participants connected to leaderboard by its ID.
|
|
141
141
|
*LeaderboardApi* | [**leaderboard_post**](rapidata/api_client/docs/LeaderboardApi.md#leaderboard_post) | **POST** /leaderboard | Creates a new leaderboard with the specified name and criteria.
|
|
@@ -2,106 +2,135 @@ from typing import Optional, Any
|
|
|
2
2
|
from rapidata.api_client.api_client import ApiClient, rest, ApiResponse, ApiResponseT
|
|
3
3
|
from rapidata.api_client.exceptions import ApiException
|
|
4
4
|
import json
|
|
5
|
+
import threading
|
|
6
|
+
from contextlib import contextmanager
|
|
5
7
|
from rapidata.rapidata_client.logging import logger
|
|
6
8
|
|
|
9
|
+
# Thread-local storage for controlling error logging
|
|
10
|
+
_thread_local = threading.local()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@contextmanager
|
|
14
|
+
def suppress_rapidata_error_logging():
|
|
15
|
+
"""Context manager to suppress error logging for RapidataApiClient calls."""
|
|
16
|
+
old_value = getattr(_thread_local, "suppress_error_logging", False)
|
|
17
|
+
_thread_local.suppress_error_logging = True
|
|
18
|
+
try:
|
|
19
|
+
yield
|
|
20
|
+
finally:
|
|
21
|
+
_thread_local.suppress_error_logging = old_value
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _should_suppress_error_logging() -> bool:
|
|
25
|
+
"""Check if error logging should be suppressed for the current thread."""
|
|
26
|
+
return getattr(_thread_local, "suppress_error_logging", False)
|
|
27
|
+
|
|
28
|
+
|
|
7
29
|
class RapidataError(Exception):
|
|
8
30
|
"""Custom error class for Rapidata API errors."""
|
|
9
|
-
|
|
31
|
+
|
|
10
32
|
def __init__(
|
|
11
|
-
self,
|
|
12
|
-
status_code: Optional[int] = None,
|
|
13
|
-
message: str | None = None,
|
|
33
|
+
self,
|
|
34
|
+
status_code: Optional[int] = None,
|
|
35
|
+
message: str | None = None,
|
|
14
36
|
original_exception: Exception | None = None,
|
|
15
|
-
details: Any = None
|
|
37
|
+
details: Any = None,
|
|
16
38
|
):
|
|
17
39
|
self.status_code = status_code
|
|
18
40
|
self.message = message
|
|
19
41
|
self.original_exception = original_exception
|
|
20
42
|
self.details = details
|
|
21
|
-
|
|
43
|
+
|
|
22
44
|
# Create a nice error message
|
|
23
45
|
error_msg = "Rapidata API Error"
|
|
24
46
|
if status_code:
|
|
25
47
|
error_msg += f" ({status_code})"
|
|
26
48
|
if message:
|
|
27
49
|
error_msg += f": {message}"
|
|
28
|
-
|
|
50
|
+
|
|
29
51
|
super().__init__(error_msg)
|
|
30
52
|
|
|
31
53
|
def __str__(self):
|
|
32
|
-
"""Return a string representation of the error."""
|
|
54
|
+
"""Return a string representation of the error."""
|
|
33
55
|
# Extract information from message if available
|
|
34
56
|
title = None
|
|
35
57
|
errors = None
|
|
36
58
|
trace_id = None
|
|
37
|
-
|
|
59
|
+
|
|
38
60
|
# Try to extract from details if available and is a dict
|
|
39
61
|
if self.details and isinstance(self.details, dict):
|
|
40
|
-
title = self.details.get(
|
|
41
|
-
errors = self.details.get(
|
|
42
|
-
trace_id = self.details.get(
|
|
43
|
-
|
|
62
|
+
title = self.details.get("title")
|
|
63
|
+
errors = self.details.get("errors")
|
|
64
|
+
trace_id = self.details.get("traceId")
|
|
65
|
+
|
|
44
66
|
# Build the error string
|
|
45
67
|
error_parts = []
|
|
46
|
-
|
|
68
|
+
|
|
47
69
|
# Main error line
|
|
48
70
|
if title:
|
|
49
71
|
error_parts.append(f"{title}")
|
|
50
72
|
else:
|
|
51
73
|
error_parts.append(f"{self.message or 'Unknown error'}")
|
|
52
|
-
|
|
74
|
+
|
|
53
75
|
# Reasons
|
|
54
76
|
if errors:
|
|
55
77
|
if isinstance(errors, dict):
|
|
56
78
|
error_parts.append(f"Reasons: {json.dumps({'errors': errors})}")
|
|
57
79
|
else:
|
|
58
80
|
error_parts.append(f"Reasons: {errors}")
|
|
59
|
-
|
|
81
|
+
|
|
60
82
|
# Trace ID
|
|
61
83
|
if trace_id:
|
|
62
84
|
error_parts.append(f"Trace Id: {trace_id}")
|
|
63
85
|
else:
|
|
64
86
|
error_parts.append("Trace Id: N/A")
|
|
65
|
-
|
|
87
|
+
|
|
66
88
|
return "\n".join(error_parts)
|
|
67
89
|
|
|
90
|
+
|
|
68
91
|
class RapidataApiClient(ApiClient):
|
|
69
92
|
"""Custom API client that wraps errors in RapidataError."""
|
|
70
93
|
|
|
71
94
|
def response_deserialize(
|
|
72
95
|
self,
|
|
73
96
|
response_data: rest.RESTResponse,
|
|
74
|
-
response_types_map: Optional[dict[str, ApiResponseT]] = None
|
|
97
|
+
response_types_map: Optional[dict[str, ApiResponseT]] = None,
|
|
75
98
|
) -> ApiResponse[ApiResponseT]:
|
|
76
99
|
"""Override the response_deserialize method to catch and convert exceptions."""
|
|
77
100
|
try:
|
|
78
101
|
return super().response_deserialize(response_data, response_types_map)
|
|
79
102
|
except ApiException as e:
|
|
80
|
-
status_code = getattr(e,
|
|
103
|
+
status_code = getattr(e, "status", None)
|
|
81
104
|
message = str(e)
|
|
82
105
|
details = None
|
|
83
|
-
|
|
106
|
+
|
|
84
107
|
# Extract more detailed error message from response body if available
|
|
85
|
-
if hasattr(e,
|
|
108
|
+
if hasattr(e, "body") and e.body:
|
|
86
109
|
try:
|
|
87
110
|
body_json = json.loads(e.body)
|
|
88
111
|
if isinstance(body_json, dict):
|
|
89
|
-
if
|
|
90
|
-
message = body_json[
|
|
91
|
-
elif
|
|
92
|
-
message = body_json[
|
|
93
|
-
|
|
112
|
+
if "message" in body_json:
|
|
113
|
+
message = body_json["message"]
|
|
114
|
+
elif "error" in body_json:
|
|
115
|
+
message = body_json["error"]
|
|
116
|
+
|
|
94
117
|
# Store the full error details for debugging
|
|
95
118
|
details = body_json
|
|
96
119
|
except (json.JSONDecodeError, AttributeError):
|
|
97
120
|
# If we can't parse the body as JSON, use the original message
|
|
98
121
|
pass
|
|
99
|
-
|
|
100
|
-
error_formatted =
|
|
101
|
-
status_code=status_code,
|
|
102
|
-
message=message,
|
|
122
|
+
|
|
123
|
+
error_formatted = RapidataError(
|
|
124
|
+
status_code=status_code,
|
|
125
|
+
message=message,
|
|
103
126
|
original_exception=e,
|
|
104
|
-
details=details
|
|
127
|
+
details=details,
|
|
105
128
|
)
|
|
106
|
-
|
|
129
|
+
|
|
130
|
+
# Only log error if not suppressed
|
|
131
|
+
if not _should_suppress_error_logging():
|
|
132
|
+
logger.error("Error: %s", error_formatted)
|
|
133
|
+
else:
|
|
134
|
+
logger.debug("Suppressed Error: %s", error_formatted)
|
|
135
|
+
|
|
107
136
|
raise error_formatted from None
|
|
@@ -31,6 +31,7 @@ class RapidataLeaderboard:
|
|
|
31
31
|
show_prompt_asset: bool,
|
|
32
32
|
inverse_ranking: bool,
|
|
33
33
|
response_budget: int,
|
|
34
|
+
min_responses_per_matchup: int,
|
|
34
35
|
id: str,
|
|
35
36
|
openapi_service: OpenAPIService,
|
|
36
37
|
):
|
|
@@ -41,6 +42,7 @@ class RapidataLeaderboard:
|
|
|
41
42
|
self.__show_prompt_asset = show_prompt_asset
|
|
42
43
|
self.__inverse_ranking = inverse_ranking
|
|
43
44
|
self.__response_budget = response_budget
|
|
45
|
+
self.__min_responses_per_matchup = min_responses_per_matchup
|
|
44
46
|
self.id = id
|
|
45
47
|
|
|
46
48
|
@property
|
|
@@ -62,11 +64,41 @@ class RapidataLeaderboard:
|
|
|
62
64
|
leaderboard_id=self.id,
|
|
63
65
|
update_leaderboard_response_config_model=UpdateLeaderboardResponseConfigModel(
|
|
64
66
|
responseBudget=DetailMapper.get_budget(level_of_detail),
|
|
65
|
-
minResponses=
|
|
67
|
+
minResponses=self.__min_responses_per_matchup,
|
|
66
68
|
),
|
|
67
69
|
)
|
|
68
70
|
self.__response_budget = DetailMapper.get_budget(level_of_detail)
|
|
69
71
|
|
|
72
|
+
@property
|
|
73
|
+
def min_responses_per_matchup(self) -> int:
|
|
74
|
+
"""
|
|
75
|
+
Returns the minimum number of responses required to be considered for the leaderboard.
|
|
76
|
+
"""
|
|
77
|
+
return self.__min_responses_per_matchup
|
|
78
|
+
|
|
79
|
+
@min_responses_per_matchup.setter
|
|
80
|
+
def min_responses_per_matchup(self, min_responses: int):
|
|
81
|
+
"""
|
|
82
|
+
Sets the minimum number of responses required to be considered for the leaderboard.
|
|
83
|
+
"""
|
|
84
|
+
if not isinstance(min_responses, int):
|
|
85
|
+
raise ValueError("Min responses per matchup must be an integer")
|
|
86
|
+
|
|
87
|
+
if min_responses < 3:
|
|
88
|
+
raise ValueError("Min responses per matchup must be at least 3")
|
|
89
|
+
|
|
90
|
+
logger.debug(
|
|
91
|
+
f"Setting min responses per matchup to {min_responses} for leaderboard {self.name}"
|
|
92
|
+
)
|
|
93
|
+
self.__openapi_service.leaderboard_api.leaderboard_leaderboard_id_response_config_put(
|
|
94
|
+
leaderboard_id=self.id,
|
|
95
|
+
update_leaderboard_response_config_model=UpdateLeaderboardResponseConfigModel(
|
|
96
|
+
responseBudget=self.__response_budget,
|
|
97
|
+
minResponses=min_responses,
|
|
98
|
+
),
|
|
99
|
+
)
|
|
100
|
+
self.__min_responses_per_matchup = min_responses
|
|
101
|
+
|
|
70
102
|
@property
|
|
71
103
|
def show_prompt_asset(self) -> bool:
|
|
72
104
|
"""
|
|
@@ -172,6 +172,7 @@ class RapidataBenchmark:
|
|
|
172
172
|
leaderboard.show_prompt_asset,
|
|
173
173
|
leaderboard.is_inversed,
|
|
174
174
|
leaderboard.response_budget,
|
|
175
|
+
leaderboard.min_responses,
|
|
175
176
|
leaderboard.id,
|
|
176
177
|
self.__openapi_service,
|
|
177
178
|
)
|
|
@@ -258,6 +259,7 @@ class RapidataBenchmark:
|
|
|
258
259
|
show_prompt_asset: bool = False,
|
|
259
260
|
inverse_ranking: bool = False,
|
|
260
261
|
level_of_detail: Literal["low", "medium", "high", "very high"] = "low",
|
|
262
|
+
min_responses_per_matchup: int = 3,
|
|
261
263
|
) -> RapidataLeaderboard:
|
|
262
264
|
"""
|
|
263
265
|
Creates a new leaderboard for the benchmark.
|
|
@@ -269,7 +271,14 @@ class RapidataBenchmark:
|
|
|
269
271
|
show_prompt_asset: Whether to show the prompt asset to the users. (only works if the prompt asset is a URL) (default: False)
|
|
270
272
|
inverse_ranking: Whether to inverse the ranking of the leaderboard. (if the question is inversed, e.g. "Which video is worse?")
|
|
271
273
|
level_of_detail: The level of detail of the leaderboard. This will effect how many comparisons are done per model evaluation. (default: "low")
|
|
274
|
+
min_responses_per_matchup: The minimum number of responses required to be considered for the leaderboard. (default: 3)
|
|
272
275
|
"""
|
|
276
|
+
if not isinstance(min_responses_per_matchup, int):
|
|
277
|
+
raise ValueError("Min responses per matchup must be an integer")
|
|
278
|
+
|
|
279
|
+
if min_responses_per_matchup < 3:
|
|
280
|
+
raise ValueError("Min responses per matchup must be at least 3")
|
|
281
|
+
|
|
273
282
|
leaderboard_result = self.__openapi_service.leaderboard_api.leaderboard_post(
|
|
274
283
|
create_leaderboard_model=CreateLeaderboardModel(
|
|
275
284
|
benchmarkId=self.id,
|
|
@@ -278,7 +287,7 @@ class RapidataBenchmark:
|
|
|
278
287
|
showPrompt=show_prompt,
|
|
279
288
|
showPromptAsset=show_prompt_asset,
|
|
280
289
|
isInversed=inverse_ranking,
|
|
281
|
-
minResponses=
|
|
290
|
+
minResponses=min_responses_per_matchup,
|
|
282
291
|
responseBudget=DetailMapper.get_budget(level_of_detail),
|
|
283
292
|
)
|
|
284
293
|
)
|
|
@@ -294,6 +303,7 @@ class RapidataBenchmark:
|
|
|
294
303
|
show_prompt_asset,
|
|
295
304
|
inverse_ranking,
|
|
296
305
|
leaderboard_result.response_budget,
|
|
306
|
+
min_responses_per_matchup,
|
|
297
307
|
leaderboard_result.id,
|
|
298
308
|
self.__openapi_service,
|
|
299
309
|
)
|
|
@@ -5,7 +5,7 @@ Defines the MultiAsset class for handling multiple BaseAsset instances.
|
|
|
5
5
|
|
|
6
6
|
from rapidata.rapidata_client.datapoints.assets._base_asset import BaseAsset
|
|
7
7
|
from rapidata.rapidata_client.datapoints.assets import MediaAsset, TextAsset
|
|
8
|
-
from typing import Iterator, Sequence
|
|
8
|
+
from typing import Iterator, Sequence
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class MultiAsset(BaseAsset):
|
|
@@ -26,16 +26,16 @@ class MultiAsset(BaseAsset):
|
|
|
26
26
|
"""
|
|
27
27
|
if len(assets) != 2:
|
|
28
28
|
raise ValueError("Assets must come in pairs for comparison tasks.")
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
for asset in assets:
|
|
31
31
|
if not isinstance(asset, (TextAsset, MediaAsset)):
|
|
32
|
-
raise TypeError("All assets must be a TextAsset or MediaAsset.")
|
|
33
|
-
|
|
32
|
+
raise TypeError("All assets must be a TextAsset or MediaAsset.")
|
|
33
|
+
|
|
34
34
|
if not all(isinstance(asset, type(assets[0])) for asset in assets):
|
|
35
35
|
raise ValueError("All assets must be of the same type.")
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
self.assets = assets
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
def __len__(self) -> int:
|
|
40
40
|
"""
|
|
41
41
|
Get the number of assets in the MultiAsset.
|
|
@@ -56,6 +56,6 @@ class MultiAsset(BaseAsset):
|
|
|
56
56
|
|
|
57
57
|
def __str__(self) -> str:
|
|
58
58
|
return f"MultiAsset(assets={self.assets})"
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
def __repr__(self) -> str:
|
|
61
61
|
return f"MultiAsset(assets={self.assets})"
|