feat(chalice): insights as cards
This commit is contained in:
parent
be8a8409e0
commit
cdc22f107e
5 changed files with 91 additions and 34 deletions
|
|
@ -874,6 +874,7 @@ class MetricTableViewType(str, Enum):
|
|||
|
||||
class MetricOtherViewType(str, Enum):
|
||||
other_chart = "chart"
|
||||
list_chart = "list"
|
||||
|
||||
|
||||
class MetricType(str, Enum):
|
||||
|
|
@ -888,6 +889,7 @@ class MetricType(str, Enum):
|
|||
retention = "retention"
|
||||
stickiness = "stickiness"
|
||||
click_map = "clickMap"
|
||||
insights = "insights"
|
||||
|
||||
|
||||
class MetricOfErrors(str, Enum):
|
||||
|
|
@ -1017,6 +1019,11 @@ class CreateCardSchema(CardChartSchema):
|
|||
|
||||
return values
|
||||
|
||||
@root_validator
|
||||
def restrictions(cls, values):
|
||||
assert values.get("metric_type") != MetricType.insights, f"metricType:{MetricType.insights} not supported yet"
|
||||
return values
|
||||
|
||||
@root_validator
|
||||
def validator(cls, values):
|
||||
if values.get("metric_type") == MetricType.timeseries:
|
||||
|
|
@ -1062,7 +1069,7 @@ class CreateCardSchema(CardChartSchema):
|
|||
assert f.type == EventType.location, f"only events of type:{EventType.location} are allowed for metricOf:{MetricType.click_map}"
|
||||
|
||||
assert isinstance(values.get("view_type"), MetricOtherViewType), \
|
||||
f"viewType must be 'chart' for metricOf:{values.get('metric_of')}"
|
||||
f"viewType must be 'chart|list' for metricOf:{values.get('metric_of')}"
|
||||
|
||||
return values
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ from starlette import status
|
|||
from decouple import config
|
||||
|
||||
import schemas
|
||||
from chalicelib.core import funnels, issues, metrics, click_maps
|
||||
import schemas_ee
|
||||
from chalicelib.core import funnels, issues, metrics, click_maps, sessions_insights
|
||||
from chalicelib.utils import helper, pg_client
|
||||
from chalicelib.utils.TimeUTC import TimeUTC
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ else:
|
|||
PIE_CHART_GROUP = 5
|
||||
|
||||
|
||||
def __try_live(project_id, data: schemas.CreateCardSchema):
|
||||
def __try_live(project_id, data: schemas_ee.CreateCardSchema):
|
||||
results = []
|
||||
for i, s in enumerate(data.series):
|
||||
s.filter.startDate = data.startTimestamp
|
||||
|
|
@ -57,11 +58,11 @@ def __try_live(project_id, data: schemas.CreateCardSchema):
|
|||
return results
|
||||
|
||||
|
||||
def __is_funnel_chart(data: schemas.CreateCardSchema):
|
||||
def __is_funnel_chart(data: schemas_ee.CreateCardSchema):
|
||||
return data.metric_type == schemas.MetricType.funnel
|
||||
|
||||
|
||||
def __get_funnel_chart(project_id, data: schemas.CreateCardSchema):
|
||||
def __get_funnel_chart(project_id, data: schemas_ee.CreateCardSchema):
|
||||
if len(data.series) == 0:
|
||||
return {
|
||||
"stages": [],
|
||||
|
|
@ -72,12 +73,12 @@ def __get_funnel_chart(project_id, data: schemas.CreateCardSchema):
|
|||
return funnels.get_top_insights_on_the_fly_widget(project_id=project_id, data=data.series[0].filter)
|
||||
|
||||
|
||||
def __is_errors_list(data: schemas.CreateCardSchema):
|
||||
def __is_errors_list(data: schemas_ee.CreateCardSchema):
|
||||
return data.metric_type == schemas.MetricType.table \
|
||||
and data.metric_of == schemas.MetricOfTable.errors
|
||||
|
||||
|
||||
def __get_errors_list(project_id, user_id, data: schemas.CreateCardSchema):
|
||||
def __get_errors_list(project_id, user_id, data: schemas_ee.CreateCardSchema):
|
||||
if len(data.series) == 0:
|
||||
return {
|
||||
"total": 0,
|
||||
|
|
@ -90,12 +91,12 @@ def __get_errors_list(project_id, user_id, data: schemas.CreateCardSchema):
|
|||
return errors.search(data.series[0].filter, project_id=project_id, user_id=user_id)
|
||||
|
||||
|
||||
def __is_sessions_list(data: schemas.CreateCardSchema):
|
||||
def __is_sessions_list(data: schemas_ee.CreateCardSchema):
|
||||
return data.metric_type == schemas.MetricType.table \
|
||||
and data.metric_of == schemas.MetricOfTable.sessions
|
||||
|
||||
|
||||
def __get_sessions_list(project_id, user_id, data: schemas.CreateCardSchema):
|
||||
def __get_sessions_list(project_id, user_id, data: schemas_ee.CreateCardSchema):
|
||||
if len(data.series) == 0:
|
||||
print("empty series")
|
||||
return {
|
||||
|
|
@ -109,15 +110,15 @@ def __get_sessions_list(project_id, user_id, data: schemas.CreateCardSchema):
|
|||
return sessions.search_sessions(data=data.series[0].filter, project_id=project_id, user_id=user_id)
|
||||
|
||||
|
||||
def __is_predefined(data: schemas.CreateCardSchema):
|
||||
def __is_predefined(data: schemas_ee.CreateCardSchema):
|
||||
return data.is_template
|
||||
|
||||
|
||||
def __is_click_map(data: schemas.CreateCardSchema):
|
||||
def __is_click_map(data: schemas_ee.CreateCardSchema):
|
||||
return data.metric_type == schemas.MetricType.click_map
|
||||
|
||||
|
||||
def __get_click_map_chat(project_id, user_id, data: schemas.CreateCardSchema):
|
||||
def __get_click_map_chat(project_id, user_id, data: schemas_ee.CreateCardSchema):
|
||||
if len(data.series) == 0:
|
||||
return None
|
||||
data.series[0].filter.startDate = data.startTimestamp
|
||||
|
|
@ -126,7 +127,20 @@ def __get_click_map_chat(project_id, user_id, data: schemas.CreateCardSchema):
|
|||
data=schemas.FlatClickMapSessionsSearch(**data.series[0].filter.dict()))
|
||||
|
||||
|
||||
def merged_live(project_id, data: schemas.CreateCardSchema, user_id=None):
|
||||
# EE only
|
||||
def __is_insights(data: schemas_ee.CreateCardSchema):
|
||||
return data.metric_type == schemas.MetricType.insights
|
||||
|
||||
|
||||
# EE only
|
||||
def __get_insights_chat(project_id, user_id, data: schemas_ee.CreateCardSchema):
|
||||
return sessions_insights.fetch_selected(project_id=project_id,
|
||||
data=schemas_ee.GetInsightsSchema(startTimestamp=data.startTimestamp,
|
||||
endTimestamp=data.endTimestamp,
|
||||
categories=data.metric_value))
|
||||
|
||||
|
||||
def merged_live(project_id, data: schemas_ee.CreateCardSchema, user_id=None):
|
||||
if data.is_template:
|
||||
return get_predefined_metric(key=data.metric_of, project_id=project_id, data=data.dict())
|
||||
elif __is_funnel_chart(data):
|
||||
|
|
@ -137,6 +151,9 @@ def merged_live(project_id, data: schemas.CreateCardSchema, user_id=None):
|
|||
return __get_sessions_list(project_id=project_id, user_id=user_id, data=data)
|
||||
elif __is_click_map(data):
|
||||
return __get_click_map_chat(project_id=project_id, user_id=user_id, data=data)
|
||||
# EE only
|
||||
elif __is_insights(data):
|
||||
return __get_insights_chat(project_id=project_id, user_id=user_id, data=data)
|
||||
elif len(data.series) == 0:
|
||||
return []
|
||||
series_charts = __try_live(project_id=project_id, data=data)
|
||||
|
|
@ -150,11 +167,11 @@ def merged_live(project_id, data: schemas.CreateCardSchema, user_id=None):
|
|||
return results
|
||||
|
||||
|
||||
def __merge_metric_with_data(metric: schemas.CreateCardSchema,
|
||||
data: schemas.CardChartSchema) -> schemas.CreateCardSchema:
|
||||
def __merge_metric_with_data(metric: schemas_ee.CreateCardSchema,
|
||||
data: schemas.CardChartSchema) -> schemas_ee.CreateCardSchema:
|
||||
if data.series is not None and len(data.series) > 0:
|
||||
metric.series = data.series
|
||||
metric: schemas.CreateCardSchema = schemas.CreateCardSchema(
|
||||
metric: schemas_ee.CreateCardSchema = schemas_ee.CreateCardSchema(
|
||||
**{**data.dict(by_alias=True), **metric.dict(by_alias=True)})
|
||||
if len(data.filters) > 0 or len(data.events) > 0:
|
||||
for s in metric.series:
|
||||
|
|
@ -165,12 +182,13 @@ def __merge_metric_with_data(metric: schemas.CreateCardSchema,
|
|||
return metric
|
||||
|
||||
|
||||
def make_chart(project_id, user_id, metric_id, data: schemas.CardChartSchema, metric: schemas.CreateCardSchema = None):
|
||||
def make_chart(project_id, user_id, metric_id, data: schemas.CardChartSchema,
|
||||
metric: schemas_ee.CreateCardSchema = None):
|
||||
if metric is None:
|
||||
metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False)
|
||||
if metric is None:
|
||||
return None
|
||||
metric: schemas.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
metric: schemas_ee.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
|
||||
return merged_live(project_id=project_id, data=metric, user_id=user_id)
|
||||
|
||||
|
|
@ -179,8 +197,8 @@ def get_sessions(project_id, user_id, metric_id, data: schemas.CardSessionsSchem
|
|||
raw_metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False)
|
||||
if raw_metric is None:
|
||||
return None
|
||||
metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**raw_metric)
|
||||
metric: schemas.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
metric: schemas_ee.CreateCardSchema = schemas_ee.CreateCardSchema(**raw_metric)
|
||||
metric: schemas_ee.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
if metric is None:
|
||||
return None
|
||||
results = []
|
||||
|
|
@ -199,8 +217,8 @@ def get_funnel_issues(project_id, user_id, metric_id, data: schemas.CardSessions
|
|||
raw_metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False)
|
||||
if raw_metric is None:
|
||||
return None
|
||||
metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**raw_metric)
|
||||
metric: schemas.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
metric: schemas_ee.CreateCardSchema = schemas_ee.CreateCardSchema(**raw_metric)
|
||||
metric: schemas_ee.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
if metric is None:
|
||||
return None
|
||||
for s in metric.series:
|
||||
|
|
@ -216,8 +234,8 @@ def get_errors_list(project_id, user_id, metric_id, data: schemas.CardSessionsSc
|
|||
raw_metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False)
|
||||
if raw_metric is None:
|
||||
return None
|
||||
metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**raw_metric)
|
||||
metric: schemas.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
metric: schemas_ee.CreateCardSchema = schemas_ee.CreateCardSchema(**raw_metric)
|
||||
metric: schemas_ee.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
if metric is None:
|
||||
return None
|
||||
for s in metric.series:
|
||||
|
|
@ -244,7 +262,7 @@ def try_sessions(project_id, user_id, data: schemas.CardSessionsSchema):
|
|||
return results
|
||||
|
||||
|
||||
def create(project_id, user_id, data: schemas.CreateCardSchema, dashboard=False):
|
||||
def create(project_id, user_id, data: schemas_ee.CreateCardSchema, dashboard=False):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
_data = {}
|
||||
for i, s in enumerate(data.series):
|
||||
|
|
@ -570,7 +588,7 @@ def get_funnel_sessions_by_issue(user_id, project_id, metric_id, issue_id,
|
|||
metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False)
|
||||
if metric is None:
|
||||
return None
|
||||
metric: schemas.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
metric: schemas_ee.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data)
|
||||
if metric is None:
|
||||
return None
|
||||
for s in metric.series:
|
||||
|
|
@ -606,7 +624,7 @@ def make_chart_from_card(project_id, user_id, metric_id, data: schemas.CardChart
|
|||
include_dashboard=False)
|
||||
if raw_metric is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="card not found")
|
||||
metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**raw_metric)
|
||||
metric: schemas_ee.CreateCardSchema = schemas_ee.CreateCardSchema(**raw_metric)
|
||||
if metric.is_template:
|
||||
return get_predefined_metric(key=metric.metric_of, project_id=project_id, data=data.dict())
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -147,8 +147,6 @@ def query_requests_by_period(project_id, start_time, end_time, time_step, conn=N
|
|||
|
||||
def query_most_errors_by_period(project_id, start_time, end_time, time_step, conn=None):
|
||||
function, steps = __handle_timestep(time_step)
|
||||
print(function)
|
||||
print(steps)
|
||||
query = f"""WITH {function.format(f"toDateTime64('{start_time}', 0)")} as start,
|
||||
{function.format(f"toDateTime64('{end_time}', 0)")} as end
|
||||
SELECT T1.hh, count(T2.session_id) as sessions, T2.name as names,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from typing import Union
|
|||
from fastapi import Body, Depends
|
||||
|
||||
import schemas
|
||||
import schemas_ee
|
||||
from chalicelib.core import dashboards, custom_metrics, funnels
|
||||
from or_dependencies import OR_context, OR_scope
|
||||
from routers.base import get_routers
|
||||
|
|
@ -62,7 +63,7 @@ def add_card_to_dashboard(projectId: int, dashboardId: int,
|
|||
@app.post('/{projectId}/dashboards/{dashboardId}/metrics', tags=["dashboard"])
|
||||
@app.put('/{projectId}/dashboards/{dashboardId}/metrics', tags=["dashboard"])
|
||||
def create_metric_and_add_to_dashboard(projectId: int, dashboardId: int,
|
||||
data: schemas.CreateCardSchema = Body(...),
|
||||
data: schemas_ee.CreateCardSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": dashboards.create_metric_add_widget(project_id=projectId, user_id=context.user_id,
|
||||
dashboard_id=dashboardId, data=data)}
|
||||
|
|
@ -100,7 +101,7 @@ def remove_widget_from_dashboard(projectId: int, dashboardId: int, widgetId: int
|
|||
@app.put('/{projectId}/metrics/try', tags=["dashboard"])
|
||||
@app.post('/{projectId}/custom_metrics/try', tags=["customMetrics"])
|
||||
@app.put('/{projectId}/custom_metrics/try', tags=["customMetrics"])
|
||||
def try_card(projectId: int, data: schemas.CreateCardSchema = Body(...),
|
||||
def try_card(projectId: int, data: schemas_ee.CreateCardSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": custom_metrics.merged_live(project_id=projectId, data=data, user_id=context.user_id)}
|
||||
|
||||
|
|
@ -139,7 +140,7 @@ def get_cards(projectId: int, context: schemas.CurrentContext = Depends(OR_conte
|
|||
@app.put('/{projectId}/metrics', tags=["dashboard"])
|
||||
@app.post('/{projectId}/custom_metrics', tags=["customMetrics"])
|
||||
@app.put('/{projectId}/custom_metrics', tags=["customMetrics"])
|
||||
def create_card(projectId: int, data: schemas.CreateCardSchema = Body(...),
|
||||
def create_card(projectId: int, data: schemas_ee.CreateCardSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return custom_metrics.create(project_id=projectId, user_id=context.user_id, data=data)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
from typing import Optional, List, Literal
|
||||
from enum import Enum
|
||||
from typing import Optional, List, Union, Literal
|
||||
|
||||
from pydantic import BaseModel, Field, EmailStr
|
||||
from pydantic import root_validator
|
||||
|
||||
import schemas
|
||||
from chalicelib.utils.TimeUTC import TimeUTC
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Permissions(str, Enum):
|
||||
|
|
@ -134,3 +135,35 @@ class AssistRecordSearchPayloadSchema(schemas._PaginatedSchema):
|
|||
|
||||
class Config:
|
||||
alias_generator = schemas.attribute_to_camel_case
|
||||
|
||||
|
||||
# TODO: move these to schema when Insights is supported on PG
|
||||
class MetricOfInsights(str, Enum):
|
||||
issue_categories = "issueCategories"
|
||||
|
||||
|
||||
class CreateCardSchema(schemas.CreateCardSchema):
|
||||
metric_of: Union[schemas.MetricOfTimeseries, schemas.MetricOfTable, \
|
||||
schemas.MetricOfErrors, schemas.MetricOfPerformance, \
|
||||
schemas.MetricOfResources, schemas.MetricOfWebVitals, \
|
||||
schemas.MetricOfClickMap, MetricOfInsights] = Field(default=schemas.MetricOfTable.user_id)
|
||||
metric_value: List[Union[schemas.IssueType, InsightCategories]] = Field(default=[])
|
||||
|
||||
@root_validator
|
||||
def restrictions(cls, values):
|
||||
return values
|
||||
|
||||
@root_validator
|
||||
def validator(cls, values):
|
||||
values = super().validator(values)
|
||||
if values.get("metric_type") == schemas.MetricType.insights:
|
||||
assert values.get("view_type") == schemas.MetricOtherViewType.list_chart, \
|
||||
f"viewType must be 'list' for metricOf:{values.get('metric_of')}"
|
||||
assert isinstance(values.get("metric_of"), MetricOfInsights), \
|
||||
f"metricOf must be of type {MetricOfInsights} for metricType:{schemas.MetricType.insights}"
|
||||
if values.get("metric_value") is not None and len(values.get("metric_value")) > 0:
|
||||
for i in values.get("metric_value"):
|
||||
assert isinstance(i, InsightCategories), \
|
||||
f"metricValue should be of type [InsightCategories] for metricType:{schemas.MetricType.insights}"
|
||||
|
||||
return values
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue