Skip to content

Commit

Permalink
fix: update when histogram and table calls are made (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
cabreraalex authored Sep 12, 2023
1 parent 4ebfde2 commit c48b35a
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 117 deletions.
4 changes: 2 additions & 2 deletions backend/zeno_backend/processing/filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ def filter_to_sql(
]:
val = "True" if str(f.value).lower() == "true" else "False"
else:
val = str(f.value)
val = f.value
if f.operation == Operation.LIKE or f.operation == Operation.ILIKE:
val = "%" + val + "%"
val = "%" + str(val) + "%"
column_id = (
f.column.id
if f.column.model is None or model is None
Expand Down
44 changes: 25 additions & 19 deletions backend/zeno_backend/processing/histogram_processing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Functions for creating the frontend metadata histograms."""

import asyncio

import numpy as np
import pandas as pd
Expand All @@ -17,7 +16,7 @@
from zeno_backend.processing.metrics.map import metric_map


async def histogram_bucket(project_uuid: str, col: ZenoColumn, num_bins: int | str):
def histogram_bucket(project_uuid: str, col: ZenoColumn, num_bins: int | str):
"""Calculate the histogram buckets for a single column.
Args:
Expand Down Expand Up @@ -64,7 +63,7 @@ async def histogram_bucket(project_uuid: str, col: ZenoColumn, num_bins: int | s
return []


async def histogram_buckets(
def histogram_buckets(
project: str, req: list[ZenoColumn], num_bins: int | str = "doane"
) -> list[list[HistogramBucket]]:
"""Calculate the histogram buckets for a list of columns.
Expand All @@ -81,12 +80,13 @@ async def histogram_buckets(
Returns:
List[List[HistogramBucket]]: for each zeno column return a list of buckets
"""
tasks = [histogram_bucket(project, col, num_bins) for col in req]
res = await asyncio.gather(*tasks)
res = []
for col in req:
res.append(histogram_bucket(project, col, num_bins))
return res


async def histogram_metric_task(
def histogram_metric_task(
request: HistogramRequest,
col_request: HistogramColumnRequest,
bucket: HistogramBucket,
Expand Down Expand Up @@ -122,7 +122,7 @@ async def histogram_metric_task(
)


async def histogram_count(
def histogram_count(
request: HistogramRequest,
col_request: HistogramColumnRequest,
project_uuid: str,
Expand Down Expand Up @@ -198,14 +198,15 @@ async def histogram_count(
else:
return []
else:
tasks = [
histogram_metric_task(request, col_request, b, project_uuid, filter_sql)
for b in col_request.buckets
]
return await asyncio.gather(*tasks)
res = []
for b in col_request.buckets:
res.append(
histogram_metric_task(request, col_request, b, project_uuid, filter_sql)
)
return res


async def histogram_counts(
def histogram_counts(
project_uuid: str, req: HistogramRequest
) -> list[list[HistogramBucket]]:
"""Calculate count and optionally metric for each bucket in each column histogram.
Expand All @@ -223,11 +224,16 @@ async def histogram_counts(
filter_sql = table_filter(
project_uuid, req.model, req.filter_predicates, req.data_ids
)
tasks = [
histogram_count(
req, r, project_uuid, filter_sql, project_obj.calculate_histogram_metrics
res = []
for r in req.column_requests:
res.append(
histogram_count(
req,
r,
project_uuid,
filter_sql,
project_obj.calculate_histogram_metrics,
)
)
for r in req.column_requests
]
res = await asyncio.gather(*tasks)

return res
17 changes: 8 additions & 9 deletions backend/zeno_backend/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,10 @@ def get_project_state(
status_code=status.HTTP_404_NOT_FOUND, detail="Project not found"
)
if not util.access_valid(project_uuid, request):
return Response(status_code=401)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Project is private",
)
user = select.user(current_user["username"])
if user is not None:
if user.name == project.owner_name:
Expand Down Expand Up @@ -425,24 +428,20 @@ def get_metrics_for_slices(req: MetricRequest, project: str, request: Request):
response_model=list[list[HistogramBucket]],
tags=["zeno"],
)
async def get_histogram_buckets(
req: list[ZenoColumn], project: str, request: Request
):
def get_histogram_buckets(req: list[ZenoColumn], project: str, request: Request):
if not util.access_valid(project, request):
return Response(status_code=401)
return await histogram_buckets(project, req)
return histogram_buckets(project, req)

@api_app.post(
"/histogram-counts/{project}",
response_model=list[list[HistogramBucket]],
tags=["zeno"],
)
async def calculate_histograms(
req: HistogramRequest, project: str, request: Request
):
def calculate_histograms(req: HistogramRequest, project: str, request: Request):
if not util.access_valid(project, request):
return Response(status_code=401)
return await histogram_counts(project, req)
return histogram_counts(project, req)

@api_app.get(
"/project-users/{project}",
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/lib/components/instance-views/ListView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@
// reset page on selection change
selectionPredicates.subscribe(() => {
if (currentPage === 0) {
updateTable();
} else {
if (currentPage !== 0) {
currentPage = 0;
}
});
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/lib/components/instance-views/TableView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@
// reset page on selection change
selectionPredicates.subscribe(() => {
if (currentPage === 0) {
updateTable();
} else {
if (currentPage !== 0) {
currentPage = 0;
}
});
Expand Down
109 changes: 49 additions & 60 deletions frontend/src/lib/components/metadata/Histograms.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,66 @@
import { calculateHistograms, getHistograms } from '$lib/api/metadata';
import MetadataCell from '$lib/components/metadata/cells/MetadataCell.svelte';
import { columns, metric, model, project, selectionIds, selectionPredicates } from '$lib/stores';
import { ZenoColumnType, type HistogramBucket } from '$lib/zenoapi';
import {
ZenoColumnType,
type FilterPredicateGroup,
type HistogramBucket,
type Metric
} from '$lib/zenoapi';
import { derived, type Readable } from 'svelte/store';
let metadataHistograms: Map<string, HistogramBucket[]> = new Map();
getHistograms($project?.uuid, $columns, $model).then((res) => {
calculateHistograms(
$project?.uuid,
$columns,
res,
undefined,
$selectionIds,
$model,
$metric
).then((res) => {
metadataHistograms = res;
});
});
type HistogramState = {
model: string | undefined;
metric: Metric | undefined;
selectionPredicates: FilterPredicateGroup | undefined;
};
metric.subscribe((m) => {
calculateHistograms(
$project?.uuid,
$columns,
metadataHistograms,
$selectionPredicates,
$selectionIds,
$model,
m
).then((r) => (metadataHistograms = r));
// Derived store to only update histograms once at startup.
const histogramState: Readable<HistogramState> = derived(
[model, metric, selectionPredicates],
([$model, $metric, $selectionPredicates]) => {
return {
model: $model,
metric: $metric,
selectionPredicates: $selectionPredicates
};
}
);
model.subscribe(() => {
metadataHistograms = new Map();
});
model.subscribe((m) => {
getHistograms($project?.uuid, $columns, $model).then((res) => {
histogramState.subscribe((s) => {
if (metadataHistograms.size === 0) {
getHistograms($project?.uuid, $columns, $model).then((res) => {
calculateHistograms(
$project?.uuid,
$columns,
res,
s.selectionPredicates,
$selectionIds,
s.model,
s.metric
).then((res) => {
metadataHistograms = res;
});
});
} else {
calculateHistograms(
$project?.uuid,
$columns,
res,
$selectionPredicates,
metadataHistograms,
s.selectionPredicates,
$selectionIds,
m,
$metric
).then((r) => (metadataHistograms = r));
});
});
// when the selection Ids change, update the histograms
selectionIds.subscribe((selectionIds) =>
calculateHistograms(
$project?.uuid,
$columns,
metadataHistograms,
$selectionPredicates,
selectionIds,
$model,
$metric
).then((r) => (metadataHistograms = r))
);
// Update counts and metrics when selection changes.
selectionPredicates.subscribe((sels) => {
if (metadataHistograms.size === 0) {
return;
s.model,
s.metric
).then((res) => {
metadataHistograms = res;
});
}
calculateHistograms(
$project?.uuid,
$columns,
metadataHistograms,
sels,
$selectionIds,
$model,
$metric
).then((r) => (metadataHistograms = r));
});
</script>

Expand Down
8 changes: 6 additions & 2 deletions frontend/src/lib/components/metadata/SelectionBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { editTag, metric, project } from '$lib/stores';
import type { GroupMetric } from '$lib/zenoapi';
import Button, { Group } from '@smui/button';
import CircularProgress from '@smui/circular-progress';
import ChipsWrapper from './ChipsWrapper.svelte';
export let currentResult: Promise<GroupMetric[] | undefined>;
Expand All @@ -26,11 +27,14 @@
<div
class="flex flex-wrap justify-between w-full items-center py-2.5 border-b border-grey-lighter"
>
<div>
<div class="flex">
<div />
<span class="text-grey-dark mr-3">
{$metric ? $metric.name + ':' : ''}
</span>
{#await currentResult then res}
{#await currentResult}
<CircularProgress style="height: 20px; width: 20px; margin-right:20px" indeterminate />
{:then res}
{#if res !== undefined && res.length > 0}
{#if res[0].metric !== undefined && res[0].metric !== null}
<span class="text-primary mr-3">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ export async function load({ cookies, params, url, depends }) {

OpenAPI.BASE = getEndpoint() + '/api';

const projectPublic = ZenoService.isProjectPublic(params.project);

let cognitoUser = null;
const userCookie = cookies.get('loggedIn');
if (userCookie) {
Expand All @@ -27,8 +25,6 @@ export async function load({ cookies, params, url, depends }) {
OpenAPI.HEADERS = {
Authorization: 'Bearer ' + cognitoUser.accessToken
};
} else if (!projectPublic) {
throw redirect(303, `/login?redirectTo=${url.pathname}`);
}

let project_result: ProjectState;
Expand Down
32 changes: 17 additions & 15 deletions frontend/src/routes/(app)/project/[owner]/[project]/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,23 @@
export let data;
project.set(data.project);
rowsPerPage.set(data.project.samplesPerPage ?? 10);
slices.set(data.slices);
columns.set(data.columns);
models.set(data.models);
metrics.set(data.metrics);
folders.set(data.folders);
tags.set(data.tags);
model.set(data.model);
metric.set(data.metric);
comparisonModel.set(data.comparisonModel);
comparisonColumn.set(data.comparisonColumn);
compareSort.set(data.compareSort);
metricRange.set(data.metricRange);
selections.set(data.selections);
if ($project === undefined) {
project.set(data.project);
rowsPerPage.set(data.project.samplesPerPage ?? 10);
slices.set(data.slices);
columns.set(data.columns);
models.set(data.models);
metrics.set(data.metrics);
folders.set(data.folders);
tags.set(data.tags);
model.set(data.model);
metric.set(data.metric);
comparisonModel.set(data.comparisonModel);
comparisonColumn.set(data.comparisonColumn);
compareSort.set(data.compareSort);
metricRange.set(data.metricRange);
selections.set(data.selections);
}
model.subscribe((mod) => {
// URL parameters set by selection subscription.
Expand Down

0 comments on commit c48b35a

Please sign in to comment.