diff --git a/flaskapi/flask_workflows.py b/flaskapi/flask_workflows.py index 2bbb58b4..53b3d4d4 100644 --- a/flaskapi/flask_workflows.py +++ b/flaskapi/flask_workflows.py @@ -167,6 +167,9 @@ def _deployment_mode() -> str: def _get_all_items(api_call: Callable, *args, **kwargs): """Helper function to get all items from a paginated API call.""" list_len = api_call(limit=1,*args, **kwargs).total + if "limit" not in kwargs: + kwargs["limit"] = int(np.min([50, list_len])) ## max allowed is 50 + retrieved = 0 items = [] page = 1 @@ -360,6 +363,21 @@ def _timeit(fun: Callable, N: int, *args, **kwargs): # test_job_retrieval_endpoints_speed(job_uid="aa5453be-d9e5-4e8a-a7a5-29acd113f1d2", N=30) + +def test_job_retrieval_paginated(function_uid: str): + def _timeit(fun: Callable, *args, **kwargs): + import time + start_time = time.time() + result = fun(*args, **kwargs) + end_time = time.time() + _logger.info(f"Retrieved {len(result)} items in {end_time - start_time:.4f} seconds") + _logger.info(f"First item: {result[0] if result else 'No items retrieved'}") + _logger.info(f"Last item: {result[-1] if result else 'No items retrieved'}") + _logger.info(f"That is {(end_time - start_time)/len(result):.2f} seconds per item") + _timeit(_get_all_items, api_call=functions_api_instance.list_function_jobs_for_functionid, function_id=function_uid) # type: ignore + +# test_job_retrieval_paginated(function_uid="eea21c0d-6c2b-4cf4-91d1-116e6550cb22") + def _create_training_file_from_jobs(jobs: List[FunctionJob], input_vars: List[str], output_response: str, folder_name: str = "evaluate") -> Path: output_response_sanitized = sanitize_varnames(output_response) completed_jobs = [job for job in jobs if job["status"].lower() == "completed" or job["status"].lower() == "success"] # type: ignore diff --git a/node/src/components/JobRow.tsx b/node/src/components/JobRow.tsx index e4fa2b70..9c704b27 100644 --- a/node/src/components/JobRow.tsx +++ b/node/src/components/JobRow.tsx @@ -42,7 +42,7 @@ const JobRow = (props: JobRowProps) => { ? Object.entries(job.job.outputs).map(([key, value], idx) => { return ( - {key} : {(value as number).toExponential(3)}{", "} + {key} : {(value as number).toPrecision(3)}{", "} ); }) @@ -61,7 +61,7 @@ const JobRow = (props: JobRowProps) => { const inputs = Object.entries(job.job.inputs).map(([key, value], idx) => { return ( - {key} : {(value as number).toExponential(3)}{", "} + {key} : {(value as number).toPrecision(3)}{", "} ); }) diff --git a/node/src/components/Metric.tsx b/node/src/components/Metric.tsx index de7c5e7a..4dde72eb 100644 --- a/node/src/components/Metric.tsx +++ b/node/src/components/Metric.tsx @@ -4,9 +4,10 @@ type MetricPropsType = { metricName: string; metricValue: number; color?: TypographyProps['color'] + percent_error?: number; } const Metric = (props: MetricPropsType) => { - const { metricName, metricValue, color } = props; + const { metricName, metricValue, color, percent_error } = props; return ( { fontWeight={100} color={color} > - {metricName}: {metricValue.toFixed(4)} + {metricName}: {percent_error + ? <>{metricValue.toPrecision(3)} ({percent_error.toPrecision(2)}% std) + : {metricValue.toPrecision(3)}} ) } diff --git a/node/src/components/navigation/Header.tsx b/node/src/components/navigation/Header.tsx index 88db5ee8..8c91bec8 100644 --- a/node/src/components/navigation/Header.tsx +++ b/node/src/components/navigation/Header.tsx @@ -47,7 +47,6 @@ const types: { [key in HeaderTypes]: TypographyVariant } = { function Header(props: HeaderProps) { const { tabTitle, infoText, ExtendedInfoText, headerType, helpContents } = props; - console.log("tabTitle: ", tabTitle, "infoText", infoText) return ( diff --git a/node/src/components/plots/SuMoValidation.tsx b/node/src/components/plots/SuMoValidation.tsx index ec69eaf2..73d677a5 100644 --- a/node/src/components/plots/SuMoValidation.tsx +++ b/node/src/components/plots/SuMoValidation.tsx @@ -44,7 +44,7 @@ const SuMoValidation = () => { (sum: number, value: number) => sum + Math.pow(value - mean_y, 2), 0 ) / - (y.length - 1) + (y.length - 1) ); const mean_y_hat = y_hat.reduce((a: number, b: number) => a + b, 0) / y_hat.length; @@ -53,8 +53,11 @@ const SuMoValidation = () => { (sum: number, value: number) => sum + Math.pow(value - mean_y_hat, 2), 0 ) / - (y_hat.length - 1) + (y_hat.length - 1) ); + + const mae_percent_error = mae / std_y * 100 + const rmse_percent_error = rmse / std_y * 100 const cvMetricsData = { mean_y: mean_y, std_y: std_y, @@ -62,6 +65,8 @@ const SuMoValidation = () => { std_y_hat: std_y_hat, mae: mae, rmse: rmse, + mae_percent_error: mae_percent_error, + rmse_percent_error: rmse_percent_error, }; setCvMetrics(cvMetricsData); console.log("Registered cvMetrics: ", cvMetricsData); @@ -145,6 +150,16 @@ const SuMoValidation = () => { }); }; + const getPercentErrorColor = (percent_error: number) => { + if (percent_error < 10) { + return "green" + } else if (percent_error < 30) { + return "orange" + } else { + return "red" + } + } + useEffect(() => { const run = async () => { const jobs = filterSelectedJobList(); @@ -260,8 +275,18 @@ const SuMoValidation = () => { /> - - + + ) : ( diff --git a/node/src/global.d.ts b/node/src/global.d.ts index bc97e885..731c3c6e 100644 --- a/node/src/global.d.ts +++ b/node/src/global.d.ts @@ -139,4 +139,6 @@ type cvMetricsType = { std_y_hat: number; mae: number; rmse: number; + mae_percent_error: number; + rmse_percent_error: number; }; \ No newline at end of file