10
10
import logging
11
11
import os
12
12
import typing
13
+ import http
13
14
import pydantic
14
15
from concurrent .futures import ThreadPoolExecutor , as_completed
15
16
from pandas import DataFrame
22
23
parse_run_set_metrics ,
23
24
)
24
25
from .serialization import deserialize_data
25
- from .types import DeserializedContent
26
+ from .simvue_types import DeserializedContent
26
27
from .utilities import check_extra , get_auth , prettify_pydantic
27
28
from .models import FOLDER_REGEX , NAME_REGEX
28
29
@@ -168,7 +169,7 @@ def get_run_id_from_name(
168
169
)
169
170
170
171
json_response = self ._get_json_from_response (
171
- expected_status = [200 ],
172
+ expected_status = [http . HTTPStatus . OK ],
172
173
scenario = "Retrieval of run ID from name" ,
173
174
response = response ,
174
175
)
@@ -218,12 +219,12 @@ def get_run(self, run_id: str) -> typing.Optional[dict[str, typing.Any]]:
218
219
)
219
220
220
221
json_response = self ._get_json_from_response (
221
- expected_status = [200 , 404 ],
222
+ expected_status = [http . HTTPStatus . OK , http . HTTPStatus . NOT_FOUND ],
222
223
scenario = f"Retrieval of run '{ run_id } '" ,
223
224
response = response ,
224
225
)
225
226
226
- if response .status_code == 404 :
227
+ if response .status_code == http . HTTPStatus . NOT_FOUND :
227
228
return None
228
229
229
230
if not isinstance (json_response , dict ):
@@ -339,7 +340,9 @@ def get_runs(
339
340
raise ValueError ("Invalid format specified" )
340
341
341
342
json_response = self ._get_json_from_response (
342
- expected_status = [200 ], scenario = "Run retrieval" , response = response
343
+ expected_status = [http .HTTPStatus .OK ],
344
+ scenario = "Run retrieval" ,
345
+ response = response ,
343
346
)
344
347
345
348
if not isinstance (json_response , dict ):
@@ -381,7 +384,7 @@ def delete_run(self, run_identifier: str) -> typing.Optional[dict]:
381
384
)
382
385
383
386
json_response = self ._get_json_from_response (
384
- expected_status = [200 ],
387
+ expected_status = [http . HTTPStatus . OK ],
385
388
scenario = f"Deletion of run '{ run_identifier } '" ,
386
389
response = response ,
387
390
)
@@ -416,7 +419,7 @@ def _get_folder_id_from_path(self, path: str) -> typing.Optional[str]:
416
419
)
417
420
418
421
if (
419
- response .status_code == 200
422
+ response .status_code == http . HTTPStatus . OK
420
423
and (response_data := response .json ().get ("data" ))
421
424
and (identifier := response_data [0 ].get ("id" ))
422
425
):
@@ -458,7 +461,7 @@ def delete_runs(
458
461
f"{ self ._url } /api/folders/{ folder_id } " , headers = self ._headers , params = params
459
462
)
460
463
461
- if response .status_code == 200 :
464
+ if response .status_code == http . HTTPStatus . OK :
462
465
if runs := response .json ().get ("runs" , []):
463
466
logger .debug (f"Runs from '{ folder_path } ' deleted successfully: { runs } " )
464
467
else :
@@ -523,7 +526,7 @@ def delete_folder(
523
526
)
524
527
525
528
json_response = self ._get_json_from_response (
526
- expected_status = [200 , 404 ],
529
+ expected_status = [http . HTTPStatus . OK , http . HTTPStatus . NOT_FOUND ],
527
530
scenario = f"Deletion of folder '{ folder_path } '" ,
528
531
response = response ,
529
532
)
@@ -551,7 +554,7 @@ def delete_alert(self, alert_id: str) -> None:
551
554
f"{ self ._url } /api/alerts/{ alert_id } " , headers = self ._headers
552
555
)
553
556
554
- if response .status_code == 200 :
557
+ if response .status_code == http . HTTPStatus . OK :
555
558
logger .debug (f"Alert '{ alert_id } ' deleted successfully" )
556
559
return
557
560
@@ -587,7 +590,7 @@ def list_artifacts(self, run_id: str) -> list[dict[str, typing.Any]]:
587
590
)
588
591
589
592
json_response = self ._get_json_from_response (
590
- expected_status = [200 ],
593
+ expected_status = [http . HTTPStatus . OK ],
591
594
scenario = f"Retrieval of artifacts for run '{ run_id } " ,
592
595
response = response ,
593
596
)
@@ -613,7 +616,7 @@ def _retrieve_artifact_from_server(
613
616
)
614
617
615
618
json_response = self ._get_json_from_response (
616
- expected_status = [200 , 404 ],
619
+ expected_status = [http . HTTPStatus . OK , http . HTTPStatus . NOT_FOUND ],
617
620
scenario = f"Retrieval of artifact '{ name } ' for run '{ run_id } '" ,
618
621
response = response ,
619
622
)
@@ -652,7 +655,7 @@ def abort_run(self, run_id: str, reason: str) -> typing.Union[dict, list]:
652
655
)
653
656
654
657
json_response = self ._get_json_from_response (
655
- expected_status = [200 , 404 ],
658
+ expected_status = [http . HTTPStatus . OK , http . HTTPStatus . NOT_FOUND ],
656
659
scenario = f"Abort of run '{ run_id } '" ,
657
660
response = response ,
658
661
)
@@ -846,7 +849,7 @@ def get_artifacts_as_files(
846
849
)
847
850
848
851
self ._get_json_from_response (
849
- expected_status = [200 ],
852
+ expected_status = [http . HTTPStatus . OK ],
850
853
scenario = f"Download of artifacts for run '{ run_id } '" ,
851
854
response = response ,
852
855
)
@@ -936,7 +939,9 @@ def get_folders(
936
939
)
937
940
938
941
json_response = self ._get_json_from_response (
939
- expected_status = [200 ], scenario = "Retrieval of folders" , response = response
942
+ expected_status = [http .HTTPStatus .OK ],
943
+ scenario = "Retrieval of folders" ,
944
+ response = response ,
940
945
)
941
946
942
947
if not isinstance (json_response , dict ):
@@ -979,7 +984,7 @@ def get_metrics_names(self, run_id: str) -> list[str]:
979
984
)
980
985
981
986
json_response = self ._get_json_from_response (
982
- expected_status = [200 ],
987
+ expected_status = [http . HTTPStatus . OK ],
983
988
scenario = f"Request for metric names for run '{ run_id } '" ,
984
989
response = response ,
985
990
)
@@ -1013,7 +1018,7 @@ def _get_run_metrics_from_server(
1013
1018
)
1014
1019
1015
1020
json_response = self ._get_json_from_response (
1016
- expected_status = [200 ],
1021
+ expected_status = [http . HTTPStatus . OK ],
1017
1022
scenario = f"Retrieval of metrics '{ metric_names } ' in " f"runs '{ run_ids } '" ,
1018
1023
response = metrics_response ,
1019
1024
)
@@ -1270,7 +1275,7 @@ def get_events(
1270
1275
)
1271
1276
1272
1277
json_response = self ._get_json_from_response (
1273
- expected_status = [200 ],
1278
+ expected_status = [http . HTTPStatus . OK ],
1274
1279
scenario = f"Retrieval of events for run '{ run_id } '" ,
1275
1280
response = response ,
1276
1281
)
@@ -1285,16 +1290,19 @@ def get_events(
1285
1290
@prettify_pydantic
1286
1291
@pydantic .validate_call
1287
1292
def get_alerts (
1288
- self , run_id : str , critical_only : bool = True , names_only : bool = True
1293
+ self ,
1294
+ run_id : typing .Optional [str ] = None ,
1295
+ critical_only : bool = True ,
1296
+ names_only : bool = True ,
1289
1297
) -> list [dict [str , typing .Any ]]:
1290
1298
"""Retrieve alerts for a given run
1291
1299
1292
1300
Parameters
1293
1301
----------
1294
- run_id : str
1302
+ run_id : str | None
1295
1303
The ID of the run to find alerts for
1296
1304
critical_only : bool, optional
1297
- Whether to only return details about alerts which are currently critical, by default True
1305
+ If a run is specified, whether to only return details about alerts which are currently critical, by default True
1298
1306
names_only: bool, optional
1299
1307
Whether to only return the names of the alerts (otherwise return the full details of the alerts), by default True
1300
1308
@@ -1308,26 +1316,42 @@ def get_alerts(
1308
1316
RuntimeError
1309
1317
if there was a failure retrieving data from the server
1310
1318
"""
1311
- response = requests .get (f"{ self ._url } /api/runs/{ run_id } " , headers = self ._headers )
1319
+ if not run_id :
1320
+ response = requests .get (f"{ self ._url } /api/alerts/" , headers = self ._headers )
1312
1321
1313
- json_response = self ._get_json_from_response (
1314
- expected_status = [200 ],
1315
- scenario = f"Retrieval of alerts for run '{ run_id } '" ,
1316
- response = response ,
1317
- )
1322
+ json_response = self ._get_json_from_response (
1323
+ expected_status = [http .HTTPStatus .OK ],
1324
+ scenario = f"Retrieval of alerts for run '{ run_id } '" ,
1325
+ response = response ,
1326
+ )
1327
+ else :
1328
+ response = requests .get (
1329
+ f"{ self ._url } /api/runs/{ run_id } " , headers = self ._headers
1330
+ )
1331
+
1332
+ json_response = self ._get_json_from_response (
1333
+ expected_status = [200 ],
1334
+ scenario = f"Retrieval of alerts for run '{ run_id } '" ,
1335
+ response = response ,
1336
+ )
1318
1337
1319
1338
if not isinstance (json_response , dict ):
1320
1339
raise RuntimeError (
1321
1340
"Expected dictionary from JSON response when retrieving alerts"
1322
1341
)
1323
1342
1324
- if (alerts := json_response .get ("alerts" )) is None :
1343
+ if run_id and (alerts := json_response .get ("alerts" )) is None :
1325
1344
raise RuntimeError (
1326
1345
"Expected key 'alerts' in response when retrieving "
1327
1346
f"alerts for run '{ run_id } ': { json_response } "
1328
1347
)
1348
+ elif not run_id and (alerts := json_response .get ("data" )) is None :
1349
+ raise RuntimeError (
1350
+ "Expected key 'data' in response when retrieving "
1351
+ f"alerts: { json_response } "
1352
+ )
1329
1353
1330
- if critical_only :
1354
+ if run_id and critical_only :
1331
1355
if names_only :
1332
1356
return [
1333
1357
alert ["alert" ].get ("name" )
@@ -1340,7 +1364,10 @@ def get_alerts(
1340
1364
for alert in alerts
1341
1365
if alert ["status" ].get ("current" ) == "critical"
1342
1366
]
1343
- elif names_only :
1344
- return [alert ["alert" ].get ("name" ) for alert in alerts ]
1367
+ if names_only :
1368
+ if run_id :
1369
+ return [alert ["alert" ].get ("name" ) for alert in alerts ]
1370
+ else :
1371
+ return [alert .get ("name" ) for alert in alerts ]
1345
1372
1346
1373
return alerts
0 commit comments