@@ -934,24 +934,48 @@ def main():
934934 print (format_list (projects , "Projects" ))
935935 elif args .list_type == "runs" :
936936 if remote :
937- run_records = remote .predict (
937+ remote_records = remote .predict (
938938 args .project , api_name = "/get_runs_for_project"
939939 )
940- runs = [r ["name" ] if isinstance (r , dict ) else r for r in run_records ]
941- else :
942- _require_project (args .project )
943- runs = SQLiteStorage .get_runs (args .project )
944- if args .json :
940+ runs = [r ["name" ] if isinstance (r , dict ) else r for r in remote_records ]
945941 statuses = SQLiteStorage .get_run_statuses (args .project )
946- run_records = [{"name" : r , "status" : statuses .get (r )} for r in runs ]
947- print (format_json ({"project" : args .project , "runs" : run_records }))
942+ if args .json :
943+ out = [{"name" : r , "status" : statuses .get (r )} for r in runs ]
944+ print (format_json ({"project" : args .project , "runs" : out }))
945+ else :
946+ annotated = [
947+ f"{ r } [{ statuses [r ]} ]" if r in statuses and statuses [r ] else r
948+ for r in runs
949+ ]
950+ print (format_list (annotated , f"Runs in '{ args .project } '" ))
948951 else :
952+ _require_project (args .project )
953+ records = SQLiteStorage .get_run_records (args .project )
949954 statuses = SQLiteStorage .get_run_statuses (args .project )
950- annotated = [
951- f"{ r } [{ statuses [r ]} ]" if r in statuses and statuses [r ] else r
952- for r in runs
953- ]
954- print (format_list (annotated , f"Runs in '{ args .project } '" ))
955+ names = [r ["name" ] for r in records ]
956+ has_dupes = len (names ) != len (set (names ))
957+ if args .json :
958+ out = [
959+ {
960+ "id" : r ["id" ],
961+ "name" : r ["name" ],
962+ "status" : statuses .get (r ["name" ]),
963+ "started_at" : r ["created_at" ],
964+ "finished_at" : r ["finished_at" ],
965+ }
966+ for r in records
967+ ]
968+ print (format_json ({"project" : args .project , "runs" : out }))
969+ else :
970+ annotated = []
971+ for r in records :
972+ label = r ["name" ]
973+ if has_dupes :
974+ label += f" ({ r ['id' ][:8 ]} )"
975+ if statuses .get (r ["name" ]):
976+ label += f" [{ statuses [r ['name' ]]} ]"
977+ annotated .append (label )
978+ print (format_list (annotated , f"Runs in '{ args .project } '" ))
955979 elif args .list_type == "metrics" :
956980 if remote :
957981 metrics = remote .predict (
@@ -1400,9 +1424,26 @@ def main():
14001424 for r in results :
14011425 r ["config" ] = _public_config (configs .get (r ["run" ]) or {})
14021426
1427+ statuses_map = SQLiteStorage .get_run_statuses (args .project )
1428+ all_records = SQLiteStorage .get_run_records (args .project )
1429+ if status_filter is not None :
1430+ all_records = [rec for rec in all_records if statuses_map .get (rec ["name" ]) == status_filter ]
1431+ records_by_name : dict [str , list [dict ]] = {}
1432+ for rec in all_records :
1433+ records_by_name .setdefault (rec ["name" ], []).append (rec )
1434+ for r in results :
1435+ pool = records_by_name .get (r ["run" ], [])
1436+ matched = pool .pop (0 ) if pool else {}
1437+ r ["id" ] = matched .get ("id" )
1438+ r ["started_at" ] = matched .get ("created_at" )
1439+ r ["finished_at" ] = matched .get ("finished_at" )
1440+
14031441 results .sort (key = lambda x : x ["value" ], reverse = not minimize )
14041442 best = results [0 ]
14051443
1444+ run_names = [r ["run" ] for r in results ]
1445+ has_dupes = len (run_names ) != len (set (run_names ))
1446+
14061447 if args .json :
14071448 print (
14081449 format_json (
@@ -1419,41 +1460,43 @@ def main():
14191460 )
14201461 )
14211462 else :
1422- print (format_best (args .project , args .metric , minimize , args .mode , results ))
1463+ display = [
1464+ {** r , "run" : f"{ r ['run' ]} ({ r ['id' ][:8 ]} )" if has_dupes and r .get ("id" ) else r ["run" ]}
1465+ for r in results
1466+ ]
1467+ print (format_best (args .project , args .metric , minimize , args .mode , display ))
14231468 elif args .command == "compare" :
14241469 _require_project (args .project )
14251470
1426- run_names = None
1427- if args .runs :
1428- run_names = [r .strip () for r in args .runs .split ("," )]
1429-
14301471 status_filter = None if args .include_all else "finished"
1431- if run_names :
1432- all_runs = run_names
1433- else :
1434- all_runs = SQLiteStorage .get_runs (args .project )
1435- if status_filter is not None :
1436- statuses_for_filter = SQLiteStorage .get_run_statuses (args .project )
1437- all_runs = [
1438- r for r in all_runs if statuses_for_filter .get (r ) == status_filter
1439- ]
1472+ statuses = SQLiteStorage .get_run_statuses (args .project )
1473+
1474+ all_records = SQLiteStorage .get_run_records (args .project )
1475+ if args .runs :
1476+ names_filter = {r .strip () for r in args .runs .split ("," )}
1477+ all_records = [r for r in all_records if r ["name" ] in names_filter ]
1478+ elif status_filter is not None :
1479+ all_records = [r for r in all_records if statuses .get (r ["name" ]) == status_filter ]
14401480
14411481 metric_names = None
14421482 if args .metrics :
14431483 metric_names = [m .strip () for m in args .metrics .split ("," )]
14441484
14451485 if not metric_names :
14461486 metric_set = set ()
1447- for run in all_runs :
1487+ for rec in all_records :
14481488 metric_set .update (
1449- SQLiteStorage .get_all_metrics_for_run (args .project , run )
1489+ SQLiteStorage .get_all_metrics_for_run (args .project , rec [ "name" ] )
14501490 )
14511491 metric_names = sorted (metric_set )
14521492
14531493 configs = SQLiteStorage .get_all_run_configs (args .project )
1454- statuses = SQLiteStorage .get_run_statuses (args .project )
1494+ run_names = [r ["name" ] for r in all_records ]
1495+ has_dupes = len (run_names ) != len (set (run_names ))
1496+
14551497 comparison = []
1456- for run in all_runs :
1498+ for rec in all_records :
1499+ run = rec ["name" ]
14571500 run_metrics = {}
14581501 for metric in metric_names :
14591502 values = SQLiteStorage .get_final_metric_for_runs (
@@ -1467,8 +1510,11 @@ def main():
14671510 run_metrics [metric ] = values [0 ]["value" ]
14681511 comparison .append (
14691512 {
1513+ "id" : rec ["id" ],
14701514 "run" : run ,
14711515 "status" : statuses .get (run ),
1516+ "started_at" : rec ["created_at" ],
1517+ "finished_at" : rec ["finished_at" ],
14721518 "config" : _public_config (configs .get (run , {})),
14731519 "metrics" : run_metrics ,
14741520 }
@@ -1485,7 +1531,11 @@ def main():
14851531 )
14861532 )
14871533 else :
1488- print (format_compare (args .project , metric_names , comparison ))
1534+ display = [
1535+ {** e , "run" : f"{ e ['run' ]} ({ e ['id' ][:8 ]} )" if has_dupes and e .get ("id" ) else e ["run" ]}
1536+ for e in comparison
1537+ ]
1538+ print (format_compare (args .project , metric_names , display ))
14891539 elif args .command == "summary" :
14901540 _require_project (args .project )
14911541
0 commit comments