* refactor(chalice): upgraded dependencies

* refactor(chalice): upgraded dependencies
feat(chalice): support heatmaps

* feat(chalice): support table-of-issues showing user-count

* feat(chalice): support table-of-browsers showing user-count

* feat(chalice): support table-of-devices showing user-count

* feat(chalice): support table-of-URLs showing user-count
This commit is contained in:
Kraiem Taha Yassine 2024-06-21 17:09:59 +02:00 committed by GitHub
parent 05f7c33a85
commit 82d2023019
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 94 additions and 42 deletions

View file

@ -52,7 +52,8 @@ def __get_table_of_series(project_id, data: schemas.CardSchema):
results = []
for i, s in enumerate(data.series):
results.append(sessions.search2_table(data=s.filter, project_id=project_id, density=data.density,
metric_of=data.metric_of, metric_value=data.metric_value))
metric_of=data.metric_of, metric_value=data.metric_value,
metric_format=data.metric_format))
return results
@ -91,9 +92,9 @@ def __get_click_map_chart(project_id, user_id, data: schemas.CardClickMap, inclu
data.series[0].filter.filters += data.series[0].filter.events
data.series[0].filter.events = []
return heatmaps.search_short_session(project_id=project_id, user_id=user_id,
data=schemas.ClickMapSessionsSearch(
**data.series[0].filter.model_dump()),
include_mobs=include_mobs)
data=schemas.ClickMapSessionsSearch(
**data.series[0].filter.model_dump()),
include_mobs=include_mobs)
def __get_path_analysis_chart(project_id: int, user_id: int, data: schemas.CardPathAnalysis):

View file

@ -1,5 +1,5 @@
import logging
from typing import List
from typing import List, Union
import schemas
from chalicelib.core import events, metadata, projects, performance_event, sessions_favorite
@ -296,7 +296,8 @@ def search2_series(data: schemas.SessionsSearchPayloadSchema, project_id: int, d
def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, density: int,
metric_of: schemas.MetricOfTable, metric_value: List):
metric_of: schemas.MetricOfTable, metric_value: List,
metric_format: Union[schemas.MetricExtendedFormatType, schemas.MetricExtendedFormatType]):
step_size = int(metrics_helper.__get_step_size(endTimestamp=data.endTimestamp, startTimestamp=data.startTimestamp,
density=density, factor=1, decimal=True))
extra_event = None
@ -331,7 +332,6 @@ def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, de
main_col = "user_id"
extra_col = ""
extra_where = ""
pre_query = ""
distinct_on = "s.session_id"
if metric_of == schemas.MetricOfTable.user_country:
main_col = "user_country"
@ -353,25 +353,46 @@ def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, de
main_col = "path"
extra_col = ", path"
distinct_on += ",path"
main_query = cur.mogrify(f"""{pre_query}
SELECT COUNT(*) AS count,
COALESCE(SUM(users_sessions.session_count),0) AS total_sessions,
COALESCE(JSONB_AGG(users_sessions) FILTER ( WHERE rn <= 200 ), '[]'::JSONB) AS values
FROM (SELECT {main_col} AS name,
count(DISTINCT session_id) AS session_count,
ROW_NUMBER() OVER (ORDER BY count(full_sessions) DESC) AS rn
FROM (SELECT *
FROM (SELECT DISTINCT ON({distinct_on}) s.session_id, s.user_uuid,
s.user_id, s.user_os,
s.user_browser, s.user_device,
s.user_device_type, s.user_country, s.issue_types{extra_col}
{query_part}
ORDER BY s.session_id desc) AS filtred_sessions
) AS full_sessions
{extra_where}
GROUP BY {main_col}
ORDER BY session_count DESC) AS users_sessions;""",
full_args)
if metric_format == schemas.MetricExtendedFormatType.session_count:
main_query = f"""SELECT COUNT(*) AS count,
COALESCE(SUM(users_sessions.session_count),0) AS total_sessions,
COALESCE(JSONB_AGG(users_sessions) FILTER ( WHERE rn <= 200 ), '[]'::JSONB) AS values
FROM (SELECT {main_col} AS name,
count(DISTINCT session_id) AS session_count,
ROW_NUMBER() OVER (ORDER BY count(full_sessions) DESC) AS rn
FROM (SELECT *
FROM (SELECT DISTINCT ON({distinct_on}) s.session_id, s.user_uuid,
s.user_id, s.user_os,
s.user_browser, s.user_device,
s.user_device_type, s.user_country, s.issue_types{extra_col}
{query_part}
ORDER BY s.session_id desc) AS filtred_sessions
) AS full_sessions
{extra_where}
GROUP BY {main_col}
ORDER BY session_count DESC) AS users_sessions;"""
else:
main_query = f"""SELECT COUNT(*) AS count,
COALESCE(SUM(users_sessions.user_count),0) AS total_users,
COALESCE(JSONB_AGG(users_sessions) FILTER ( WHERE rn <= 200 ), '[]'::JSONB) AS values
FROM (SELECT {main_col} AS name,
count(DISTINCT user_id) AS user_count,
ROW_NUMBER() OVER (ORDER BY count(full_sessions) DESC) AS rn
FROM (SELECT *
FROM (SELECT DISTINCT ON({distinct_on}) s.session_id, s.user_uuid,
s.user_id, s.user_os,
s.user_browser, s.user_device,
s.user_device_type, s.user_country, s.issue_types{extra_col}
{query_part}
AND s.user_id IS NOT NULL
AND s.user_id !=''
ORDER BY s.session_id desc) AS filtred_sessions
) AS full_sessions
{extra_where}
GROUP BY {main_col}
ORDER BY user_count DESC) AS users_sessions;"""
main_query = cur.mogrify(main_query, full_args)
logging.debug("--------------------")
logging.debug(main_query)
logging.debug("--------------------")

View file

@ -578,6 +578,11 @@ class MetricFormatType(str, Enum):
session_count = 'sessionCount'
class MetricExtendedFormatType(str, Enum):
session_count = 'sessionCount'
user_count = 'userCount'
class HttpMethod(str, Enum):
_get = 'GET'
_head = 'HEAD'
@ -1131,6 +1136,7 @@ class CardTable(__CardSchema):
metric_type: Literal[MetricType.table]
metric_of: MetricOfTable = Field(default=MetricOfTable.user_id)
view_type: MetricTableViewType = Field(...)
metric_format: MetricExtendedFormatType = Field(default=MetricExtendedFormatType.session_count)
@model_validator(mode="before")
def __enforce_default(cls, values):
@ -1143,6 +1149,15 @@ class CardTable(__CardSchema):
values.metric_of = MetricOfTable(values.metric_of)
return values
@model_validator(mode="after")
def __validator(cls, values):
if values.metric_of not in (MetricOfTable.issues, MetricOfTable.user_browser,
MetricOfTable.user_device, MetricOfTable.user_country,
MetricOfTable.visited_url):
assert values.metric_format == MetricExtendedFormatType.session_count, \
f'metricFormat:{MetricExtendedFormatType.user_count.value} is not supported for this metricOf'
return values
class CardFunnel(__CardSchema):
metric_type: Literal[MetricType.funnel]

View file

@ -63,7 +63,8 @@ def __get_table_of_series(project_id, data: schemas.CardSchema):
results = []
for i, s in enumerate(data.series):
results.append(sessions.search2_table(data=s.filter, project_id=project_id, density=data.density,
metric_of=data.metric_of, metric_value=data.metric_value))
metric_of=data.metric_of, metric_value=data.metric_value,
metric_format=data.metric_format))
return results

View file

@ -366,7 +366,8 @@ def search2_series(data: schemas.SessionsSearchPayloadSchema, project_id: int, d
def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, density: int,
metric_of: schemas.MetricOfTable, metric_value: List):
metric_of: schemas.MetricOfTable, metric_value: List,
metric_format: Union[schemas.MetricExtendedFormatType, schemas.MetricExtendedFormatType]):
step_size = int(metrics_helper.__get_step_size(endTimestamp=data.endTimestamp, startTimestamp=data.startTimestamp,
density=density))
extra_event = None
@ -413,7 +414,6 @@ def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, de
main_col = "user_id"
extra_col = "s.user_id"
extra_where = ""
pre_query = ""
if metric_of == schemas.MetricOfTable.user_country:
main_col = "user_country"
extra_col = "s.user_country"
@ -436,19 +436,33 @@ def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, de
elif metric_of == schemas.MetricOfTable.visited_url:
main_col = "url_path"
extra_col = "s.url_path"
main_query = cur.format(f"""{pre_query}
SELECT COUNT(DISTINCT {main_col}) OVER () AS main_count,
{main_col} AS name,
count(DISTINCT session_id) AS session_count
FROM (SELECT s.session_id AS session_id,
{extra_col}
{query_part}
ORDER BY s.session_id desc) AS filtred_sessions
{extra_where}
GROUP BY {main_col}
ORDER BY session_count DESC
LIMIT %(limit_e)s OFFSET %(limit_s)s;""",
full_args)
if metric_format == schemas.MetricExtendedFormatType.session_count:
main_query = f"""SELECT COUNT(DISTINCT {main_col}) OVER () AS main_count,
{main_col} AS name,
count(DISTINCT session_id) AS session_count
FROM (SELECT s.session_id AS session_id,
{extra_col}
{query_part}) AS filtred_sessions
{extra_where}
GROUP BY {main_col}
ORDER BY session_count DESC
LIMIT %(limit_e)s OFFSET %(limit_s)s;"""
else:
main_query = f"""SELECT COUNT(DISTINCT {main_col}) OVER () AS main_count,
{main_col} AS name,
count(DISTINCT user_id) AS user_count
FROM (SELECT s.user_id AS user_id,
{extra_col}
{query_part}
WHERE isNotNull(user_id)
AND user_id != '') AS filtred_sessions
{extra_where}
GROUP BY {main_col}
ORDER BY user_count DESC
LIMIT %(limit_e)s OFFSET %(limit_s)s;"""
main_query = cur.format(main_query, full_args)
logging.debug("--------------------")
logging.debug(main_query)
logging.debug("--------------------")