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
|
@@ -14,11 +14,20 @@ from rapidata.api_client.models.campaign_artifact_model import CampaignArtifactM
|
|
|
14
14
|
from rapidata.api_client.models.order_state import OrderState
|
|
15
15
|
from rapidata.api_client.models.preview_order_model import PreviewOrderModel
|
|
16
16
|
from rapidata.api_client.models.submit_order_model import SubmitOrderModel
|
|
17
|
-
from rapidata.api_client.models.preliminary_download_model import
|
|
17
|
+
from rapidata.api_client.models.preliminary_download_model import (
|
|
18
|
+
PreliminaryDownloadModel,
|
|
19
|
+
)
|
|
18
20
|
from rapidata.api_client.models.workflow_artifact_model import WorkflowArtifactModel
|
|
19
21
|
from rapidata.rapidata_client.order.rapidata_results import RapidataResults
|
|
20
22
|
from rapidata.service.openapi_service import OpenAPIService
|
|
21
|
-
from rapidata.rapidata_client.logging import
|
|
23
|
+
from rapidata.rapidata_client.logging import (
|
|
24
|
+
logger,
|
|
25
|
+
managed_print,
|
|
26
|
+
RapidataOutputManager,
|
|
27
|
+
)
|
|
28
|
+
from rapidata.rapidata_client.api.rapidata_exception import (
|
|
29
|
+
suppress_rapidata_error_logging,
|
|
30
|
+
)
|
|
22
31
|
|
|
23
32
|
|
|
24
33
|
class RapidataOrder:
|
|
@@ -47,45 +56,53 @@ class RapidataOrder:
|
|
|
47
56
|
self.__workflow_id: str = ""
|
|
48
57
|
self.__campaign_id: str = ""
|
|
49
58
|
self.__pipeline_id: str = ""
|
|
50
|
-
self._max_retries = 10
|
|
59
|
+
self._max_retries = 10
|
|
51
60
|
self._retry_delay = 2
|
|
52
|
-
self.order_details_page =
|
|
61
|
+
self.order_details_page = (
|
|
62
|
+
f"https://app.{self.__openapi_service.environment}/order/detail/{self.id}"
|
|
63
|
+
)
|
|
53
64
|
logger.debug("RapidataOrder initialized")
|
|
54
65
|
|
|
55
66
|
@property
|
|
56
67
|
def created_at(self) -> datetime:
|
|
57
68
|
"""Returns the creation date of the order."""
|
|
58
69
|
if not self.__created_at:
|
|
59
|
-
self.__created_at = self.__openapi_service.order_api.order_order_id_get(
|
|
70
|
+
self.__created_at = self.__openapi_service.order_api.order_order_id_get(
|
|
71
|
+
self.id
|
|
72
|
+
).order_date
|
|
60
73
|
return self.__created_at
|
|
61
|
-
|
|
74
|
+
|
|
62
75
|
def run(self) -> "RapidataOrder":
|
|
63
76
|
"""Runs the order to start collecting responses."""
|
|
64
|
-
logger.info(
|
|
65
|
-
self.__openapi_service.order_api.order_order_id_submit_post(
|
|
66
|
-
|
|
67
|
-
|
|
77
|
+
logger.info("Starting order '%s'", self)
|
|
78
|
+
self.__openapi_service.order_api.order_order_id_submit_post(
|
|
79
|
+
self.id, SubmitOrderModel(ignoreFailedDatapoints=True)
|
|
80
|
+
)
|
|
81
|
+
logger.debug("Order '%s' has been started.", self)
|
|
82
|
+
managed_print(
|
|
83
|
+
f"Order '{self.name}' is now viewable under: {self.order_details_page}"
|
|
84
|
+
)
|
|
68
85
|
return self
|
|
69
86
|
|
|
70
87
|
def pause(self) -> None:
|
|
71
88
|
"""Pauses the order."""
|
|
72
|
-
logger.info(
|
|
89
|
+
logger.info("Pausing order '%s'", self)
|
|
73
90
|
self.__openapi_service.order_api.order_order_id_pause_post(self.id)
|
|
74
|
-
logger.debug(
|
|
91
|
+
logger.debug("Order '%s' has been paused.", self)
|
|
75
92
|
managed_print(f"Order '{self}' has been paused.")
|
|
76
93
|
|
|
77
94
|
def unpause(self) -> None:
|
|
78
95
|
"""Unpauses/resumes the order."""
|
|
79
|
-
logger.info(
|
|
96
|
+
logger.info("Unpausing order '%s'", self)
|
|
80
97
|
self.__openapi_service.order_api.order_order_id_resume_post(self.id)
|
|
81
|
-
logger.debug(
|
|
98
|
+
logger.debug("Order '%s' has been unpaused.", self)
|
|
82
99
|
managed_print(f"Order '{self}' has been unpaused.")
|
|
83
100
|
|
|
84
101
|
def delete(self) -> None:
|
|
85
102
|
"""Deletes the order."""
|
|
86
|
-
logger.info(
|
|
103
|
+
logger.info("Deleting order '%s'", self)
|
|
87
104
|
self.__openapi_service.order_api.order_order_id_delete(self.id)
|
|
88
|
-
logger.debug(
|
|
105
|
+
logger.debug("Order '%s' has been deleted.", self)
|
|
89
106
|
managed_print(f"Order '{self}' has been deleted.")
|
|
90
107
|
|
|
91
108
|
def get_status(self) -> str:
|
|
@@ -104,31 +121,37 @@ class RapidataOrder:
|
|
|
104
121
|
"""
|
|
105
122
|
return self.__openapi_service.order_api.order_order_id_get(self.id).state
|
|
106
123
|
|
|
107
|
-
def display_progress_bar(self, refresh_rate: int=5) -> None:
|
|
124
|
+
def display_progress_bar(self, refresh_rate: int = 5) -> None:
|
|
108
125
|
"""
|
|
109
126
|
Displays a progress bar for the order processing using tqdm.
|
|
110
|
-
|
|
111
|
-
Args:
|
|
127
|
+
|
|
128
|
+
Args:
|
|
112
129
|
refresh_rate: How often to refresh the progress bar, in seconds.
|
|
113
130
|
"""
|
|
114
131
|
if refresh_rate < 1:
|
|
115
132
|
raise ValueError("refresh_rate must be at least 1")
|
|
116
|
-
|
|
133
|
+
|
|
117
134
|
if self.get_status() == OrderState.CREATED:
|
|
118
135
|
raise Exception("Order has not been started yet. Please start it first.")
|
|
119
|
-
|
|
136
|
+
|
|
120
137
|
while self.get_status() == OrderState.SUBMITTED:
|
|
121
|
-
managed_print(
|
|
138
|
+
managed_print(
|
|
139
|
+
f"Order '{self}' is submitted and being reviewed. Standby...", end="\r"
|
|
140
|
+
)
|
|
122
141
|
sleep(1)
|
|
123
142
|
|
|
124
143
|
if self.get_status() == OrderState.MANUALREVIEW:
|
|
125
144
|
raise Exception(
|
|
126
|
-
f"Order '{self}' is in manual review. It might take some time to start. "
|
|
127
|
-
"To speed up the process, contact support (info@rapidata.ai).\n"
|
|
128
|
-
"Once started, run this method again to display the progress bar."
|
|
145
|
+
f"Order '{self}' is in manual review. It might take some time to start. To speed up the process, contact support (info@rapidata.ai).\nOnce started, run this method again to display the progress bar."
|
|
129
146
|
)
|
|
130
|
-
|
|
131
|
-
with tqdm(
|
|
147
|
+
|
|
148
|
+
with tqdm(
|
|
149
|
+
total=100,
|
|
150
|
+
desc="Processing order",
|
|
151
|
+
unit="%",
|
|
152
|
+
bar_format="{desc}: {percentage:3.0f}%|{bar}| completed [{elapsed}<{remaining}, {rate_fmt}]",
|
|
153
|
+
disable=RapidataOutputManager.silent_mode,
|
|
154
|
+
) as pbar:
|
|
132
155
|
last_percentage = 0
|
|
133
156
|
while True:
|
|
134
157
|
current_percentage = self._workflow_progress.completion_percentage
|
|
@@ -149,8 +172,11 @@ class RapidataOrder:
|
|
|
149
172
|
progress = None
|
|
150
173
|
for _ in range(self._max_retries // 2):
|
|
151
174
|
try:
|
|
152
|
-
|
|
153
|
-
|
|
175
|
+
with suppress_rapidata_error_logging():
|
|
176
|
+
workflow_id = self.__get_workflow_id()
|
|
177
|
+
progress = self.__openapi_service.workflow_api.workflow_workflow_id_progress_get(
|
|
178
|
+
workflow_id
|
|
179
|
+
)
|
|
154
180
|
break
|
|
155
181
|
except Exception:
|
|
156
182
|
sleep(self._retry_delay * 2)
|
|
@@ -160,52 +186,71 @@ class RapidataOrder:
|
|
|
160
186
|
|
|
161
187
|
def get_results(self, preliminary_results: bool = False) -> RapidataResults:
|
|
162
188
|
"""
|
|
163
|
-
Gets the results of the order.
|
|
189
|
+
Gets the results of the order.
|
|
164
190
|
If the order is still processing, this method will block until the order is completed and then return the results.
|
|
165
191
|
|
|
166
192
|
Args:
|
|
167
|
-
preliminary_results: If True, returns the preliminary results of the order. Defaults to False.
|
|
193
|
+
preliminary_results: If True, returns the preliminary results of the order. Defaults to False.
|
|
168
194
|
Note that preliminary results are not final and may not contain all the datapoints & responses. Only the onese that are already available.
|
|
169
195
|
"""
|
|
170
|
-
logger.info(
|
|
196
|
+
logger.info("Getting results for order '%s'...", self)
|
|
171
197
|
if preliminary_results and self.get_status() not in [OrderState.COMPLETED]:
|
|
172
198
|
return self.__get_preliminary_results()
|
|
173
|
-
|
|
199
|
+
|
|
174
200
|
elif preliminary_results and self.get_status() in [OrderState.COMPLETED]:
|
|
175
201
|
managed_print("Order is already completed. Returning final results.")
|
|
176
202
|
|
|
177
|
-
while self.get_status() not in [
|
|
203
|
+
while self.get_status() not in [
|
|
204
|
+
OrderState.COMPLETED,
|
|
205
|
+
OrderState.PAUSED,
|
|
206
|
+
OrderState.MANUALREVIEW,
|
|
207
|
+
OrderState.FAILED,
|
|
208
|
+
]:
|
|
178
209
|
sleep(5)
|
|
179
210
|
|
|
180
211
|
try:
|
|
181
|
-
return RapidataResults(
|
|
212
|
+
return RapidataResults(
|
|
213
|
+
json.loads(
|
|
214
|
+
self.__openapi_service.order_api.order_order_id_download_results_get(
|
|
215
|
+
order_id=self.id
|
|
216
|
+
)
|
|
217
|
+
)
|
|
218
|
+
)
|
|
182
219
|
except (ApiException, json.JSONDecodeError) as e:
|
|
183
220
|
raise Exception(f"Failed to get order results: {str(e)}") from e
|
|
184
|
-
|
|
221
|
+
|
|
185
222
|
def view(self) -> None:
|
|
186
223
|
"""
|
|
187
224
|
Opens the order details page in the browser.
|
|
188
|
-
|
|
225
|
+
|
|
189
226
|
Raises:
|
|
190
227
|
Exception: If the order is not in processing state.
|
|
191
228
|
"""
|
|
192
229
|
logger.info("Opening order details page in browser...")
|
|
193
230
|
could_open_browser = webbrowser.open(self.order_details_page)
|
|
194
231
|
if not could_open_browser:
|
|
195
|
-
encoded_url = urllib.parse.quote(
|
|
196
|
-
|
|
197
|
-
|
|
232
|
+
encoded_url = urllib.parse.quote(
|
|
233
|
+
self.order_details_page, safe="%/:=&?~#+!$,;'@()*[]"
|
|
234
|
+
)
|
|
235
|
+
managed_print(
|
|
236
|
+
Fore.RED
|
|
237
|
+
+ f"Please open this URL in your browser: '{encoded_url}'"
|
|
238
|
+
+ Fore.RESET
|
|
239
|
+
)
|
|
240
|
+
|
|
198
241
|
def preview(self) -> None:
|
|
199
242
|
"""
|
|
200
243
|
Opens a preview of the order in the browser.
|
|
201
|
-
|
|
244
|
+
|
|
202
245
|
Raises:
|
|
203
246
|
Exception: If the order is not in processing state.
|
|
204
247
|
"""
|
|
205
248
|
logger.info("Opening order preview in browser...")
|
|
206
249
|
if self.get_status() == OrderState.CREATED:
|
|
207
250
|
logger.info("Order is still in state created. Setting it to preview.")
|
|
208
|
-
self.__openapi_service.order_api.order_order_id_preview_post(
|
|
251
|
+
self.__openapi_service.order_api.order_order_id_preview_post(
|
|
252
|
+
self.id, PreviewOrderModel(ignoreFailedDatapoints=True)
|
|
253
|
+
)
|
|
209
254
|
logger.info("Order is now in preview state.")
|
|
210
255
|
|
|
211
256
|
campaign_id = self.__get_campaign_id()
|
|
@@ -213,14 +258,22 @@ class RapidataOrder:
|
|
|
213
258
|
could_open_browser = webbrowser.open(auth_url)
|
|
214
259
|
if not could_open_browser:
|
|
215
260
|
encoded_url = urllib.parse.quote(auth_url, safe="%/:=&?~#+!$,;'@()*[]")
|
|
216
|
-
managed_print(
|
|
261
|
+
managed_print(
|
|
262
|
+
Fore.RED
|
|
263
|
+
+ f"Please open this URL in your browser: '{encoded_url}'"
|
|
264
|
+
+ Fore.RESET
|
|
265
|
+
)
|
|
217
266
|
|
|
218
267
|
def __get_pipeline_id(self) -> str:
|
|
219
268
|
"""Internal method to fetch and cache the pipeline ID."""
|
|
220
269
|
if not self.__pipeline_id:
|
|
221
270
|
for _ in range(self._max_retries):
|
|
222
271
|
try:
|
|
223
|
-
self.__pipeline_id =
|
|
272
|
+
self.__pipeline_id = (
|
|
273
|
+
self.__openapi_service.order_api.order_order_id_get(
|
|
274
|
+
self.id
|
|
275
|
+
).pipeline_id
|
|
276
|
+
)
|
|
224
277
|
break
|
|
225
278
|
except Exception:
|
|
226
279
|
sleep(self._retry_delay)
|
|
@@ -247,9 +300,17 @@ class RapidataOrder:
|
|
|
247
300
|
pipeline_id = self.__get_pipeline_id()
|
|
248
301
|
for _ in range(self._max_retries):
|
|
249
302
|
try:
|
|
250
|
-
pipeline = self.__openapi_service.pipeline_api.pipeline_pipeline_id_get(
|
|
251
|
-
|
|
252
|
-
|
|
303
|
+
pipeline = self.__openapi_service.pipeline_api.pipeline_pipeline_id_get(
|
|
304
|
+
pipeline_id
|
|
305
|
+
)
|
|
306
|
+
self.__workflow_id = cast(
|
|
307
|
+
WorkflowArtifactModel,
|
|
308
|
+
pipeline.artifacts["workflow-artifact"].actual_instance,
|
|
309
|
+
).workflow_id
|
|
310
|
+
self.__campaign_id = cast(
|
|
311
|
+
CampaignArtifactModel,
|
|
312
|
+
pipeline.artifacts["campaign-artifact"].actual_instance,
|
|
313
|
+
).campaign_id
|
|
253
314
|
return
|
|
254
315
|
except Exception:
|
|
255
316
|
sleep(self._retry_delay)
|
|
@@ -262,7 +323,7 @@ class RapidataOrder:
|
|
|
262
323
|
download_id = self.__openapi_service.pipeline_api.pipeline_pipeline_id_preliminary_download_post(
|
|
263
324
|
pipeline_id, PreliminaryDownloadModel(sendEmail=False)
|
|
264
325
|
).download_id
|
|
265
|
-
|
|
326
|
+
|
|
266
327
|
elapsed = 0
|
|
267
328
|
timeout = 60
|
|
268
329
|
while elapsed < timeout:
|
|
@@ -5,7 +5,9 @@ from rapidata import __version__
|
|
|
5
5
|
from rapidata.service.openapi_service import OpenAPIService
|
|
6
6
|
|
|
7
7
|
from rapidata.rapidata_client.order.rapidata_order_manager import RapidataOrderManager
|
|
8
|
-
from rapidata.rapidata_client.benchmark.rapidata_benchmark_manager import
|
|
8
|
+
from rapidata.rapidata_client.benchmark.rapidata_benchmark_manager import (
|
|
9
|
+
RapidataBenchmarkManager,
|
|
10
|
+
)
|
|
9
11
|
|
|
10
12
|
from rapidata.rapidata_client.validation.validation_set_manager import (
|
|
11
13
|
ValidationSetManager,
|
|
@@ -15,18 +17,19 @@ from rapidata.rapidata_client.demographic.demographic_manager import Demographic
|
|
|
15
17
|
|
|
16
18
|
from rapidata.rapidata_client.logging import logger, managed_print
|
|
17
19
|
|
|
20
|
+
|
|
18
21
|
class RapidataClient:
|
|
19
22
|
"""The Rapidata client is the main entry point for interacting with the Rapidata API. It allows you to create orders and validation sets."""
|
|
20
23
|
|
|
21
24
|
def __init__(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
self,
|
|
26
|
+
client_id: str | None = None,
|
|
27
|
+
client_secret: str | None = None,
|
|
28
|
+
environment: str = "rapidata.ai",
|
|
29
|
+
oauth_scope: str = "openid",
|
|
30
|
+
cert_path: str | None = None,
|
|
31
|
+
token: dict | None = None,
|
|
32
|
+
leeway: int = 60,
|
|
30
33
|
):
|
|
31
34
|
"""Initialize the RapidataClient. If both the client_id and client_secret are None, it will try using your credentials under "~/.config/rapidata/credentials.json".
|
|
32
35
|
If this is not successful, it will open a browser window and ask you to log in, then save your new credentials in said json file.
|
|
@@ -69,7 +72,7 @@ class RapidataClient:
|
|
|
69
72
|
|
|
70
73
|
logger.debug("Initializing RapidataBenchmarkManager")
|
|
71
74
|
self.mri = RapidataBenchmarkManager(openapi_service=self._openapi_service)
|
|
72
|
-
|
|
75
|
+
|
|
73
76
|
def reset_credentials(self):
|
|
74
77
|
"""Reset the credentials saved in the configuration file for the current environment."""
|
|
75
78
|
self._openapi_service.reset_credentials()
|
|
@@ -79,12 +82,14 @@ class RapidataClient:
|
|
|
79
82
|
response = requests.get(
|
|
80
83
|
"https://api.github.com/repos/RapidataAI/rapidata-python-sdk/releases/latest",
|
|
81
84
|
headers={"Accept": "application/vnd.github.v3+json"},
|
|
82
|
-
timeout=3
|
|
85
|
+
timeout=3,
|
|
83
86
|
)
|
|
84
87
|
if response.status_code == 200:
|
|
85
88
|
latest_version = response.json()["tag_name"].lstrip("v")
|
|
86
89
|
if version.parse(latest_version) > version.parse(__version__):
|
|
87
|
-
managed_print(
|
|
88
|
-
|
|
90
|
+
managed_print(
|
|
91
|
+
f"""A new version of the Rapidata SDK is available: {latest_version}
|
|
92
|
+
Your current version is: {__version__}"""
|
|
93
|
+
)
|
|
89
94
|
except Exception as e:
|
|
90
|
-
logger.debug(
|
|
95
|
+
logger.debug("Failed to check for updates: %s", e)
|
|
@@ -4,6 +4,7 @@ from rapidata.rapidata_client.logging import logger
|
|
|
4
4
|
from rapidata.api_client.models.update_dimensions_model import UpdateDimensionsModel
|
|
5
5
|
from rapidata.api_client.models.update_should_alert_model import UpdateShouldAlertModel
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
class RapidataValidationSet:
|
|
8
9
|
"""A class for interacting with a Rapidata validation set.
|
|
9
10
|
|
|
@@ -20,7 +21,7 @@ class RapidataValidationSet:
|
|
|
20
21
|
self.id = validation_set_id
|
|
21
22
|
self.name = name
|
|
22
23
|
self.__openapi_service = openapi_service
|
|
23
|
-
|
|
24
|
+
|
|
24
25
|
def add_rapid(self, rapid: Rapid):
|
|
25
26
|
"""Add a Rapid to the validation set.
|
|
26
27
|
|
|
@@ -36,10 +37,14 @@ class RapidataValidationSet:
|
|
|
36
37
|
Args:
|
|
37
38
|
dimensions (list[str]): The new dimensions of the validation set.
|
|
38
39
|
"""
|
|
39
|
-
logger.debug(
|
|
40
|
-
|
|
40
|
+
logger.debug(
|
|
41
|
+
"Updating dimensions for validation set %s to %s", self.id, dimensions
|
|
42
|
+
)
|
|
43
|
+
self.__openapi_service.validation_api.validation_set_validation_set_id_dimensions_put(
|
|
44
|
+
self.id, UpdateDimensionsModel(dimensions=dimensions)
|
|
45
|
+
)
|
|
41
46
|
return self
|
|
42
|
-
|
|
47
|
+
|
|
43
48
|
def update_should_alert(self, should_alert: bool):
|
|
44
49
|
"""Determines whether users should be alerted if they answer incorrectly.
|
|
45
50
|
|
|
@@ -49,10 +54,11 @@ class RapidataValidationSet:
|
|
|
49
54
|
Note:
|
|
50
55
|
The userScore dimensions which are updated when a user answers a validation task are updated regardless of the value of `should_alert`.
|
|
51
56
|
"""
|
|
52
|
-
logger.debug(
|
|
57
|
+
logger.debug(
|
|
58
|
+
"Setting shouldAlert for validation set %s to %s", self.id, should_alert
|
|
59
|
+
)
|
|
53
60
|
self.__openapi_service.validation_api.validation_set_validation_set_id_shouldalert_patch(
|
|
54
|
-
self.id,
|
|
55
|
-
UpdateShouldAlertModel(shouldAlert=should_alert)
|
|
61
|
+
self.id, UpdateShouldAlertModel(shouldAlert=should_alert)
|
|
56
62
|
)
|
|
57
63
|
return self
|
|
58
64
|
|