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