* fix(chalice): fixed Math-operators validation
refactor(chalice): search for sessions that have events for heatmaps

* refactor(chalice): search for sessions that have at least 1 location event for heatmaps

* fix(chalice): fixed Math-operators validation
refactor(chalice): search for sessions that have events for heatmaps

* refactor(chalice): search for sessions that have at least 1 location event for heatmaps

* feat(chalice): autocomplete return top 10 with stats

* fix(chalice): fixed autocomplete top 10 meta-filters

* fix(chalice): fixed multiple issues
This commit is contained in:
Kraiem Taha Yassine 2024-11-14 13:17:50 +01:00 committed by GitHub
parent c1ef27fc9b
commit db33701a18
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 50 additions and 81 deletions

View file

@ -1,4 +1,4 @@
from chalicelib.utils import pg_client, helper
from chalicelib.utils import pg_client
from chalicelib.utils.storage import StorageClient
from decouple import config

View file

@ -234,14 +234,14 @@ def __get_path_analysis_card_info(data: schemas.CardPathAnalysis):
return r
def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=False):
def create_card(project: schemas.ProjectContext, user_id, data: schemas.CardSchema, dashboard=False):
with pg_client.PostgresClient() as cur:
session_data = None
if data.metric_type == schemas.MetricType.HEAT_MAP:
if data.session_id is not None:
session_data = {"sessionId": data.session_id}
else:
session_data = __get_heat_map_chart(project_id=project_id, user_id=user_id,
session_data = __get_heat_map_chart(project=project, user_id=user_id,
data=data, include_mobs=False)
if session_data is not None:
session_data = {"sessionId": session_data["sessionId"]}
@ -253,7 +253,7 @@ def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=False):
_data[f"index_{i}"] = i
_data[f"filter_{i}"] = s.filter.json()
series_len = len(data.series)
params = {"user_id": user_id, "project_id": project_id, **data.model_dump(), **_data,
params = {"user_id": user_id, "project_id": project.project_id, **data.model_dump(), **_data,
"default_config": json.dumps(data.default_config.model_dump()), "card_info": None}
if data.metric_type == schemas.MetricType.PATH_ANALYSIS:
params["card_info"] = json.dumps(__get_path_analysis_card_info(data=data))
@ -279,7 +279,7 @@ def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=False):
r = cur.fetchone()
if dashboard:
return r["metric_id"]
return {"data": get_card(metric_id=r["metric_id"], project_id=project_id, user_id=user_id)}
return {"data": get_card(metric_id=r["metric_id"], project_id=project.project_id, user_id=user_id)}
def update_card(metric_id, user_id, project_id, data: schemas.CardSchema):

View file

@ -204,9 +204,9 @@ def pin_dashboard(project_id, user_id, dashboard_id):
return helper.dict_to_camel_case(row)
def create_metric_add_widget(project_id, user_id, dashboard_id, data: schemas.CardSchema):
metric_id = custom_metrics.create_card(project_id=project_id, user_id=user_id, data=data, dashboard=True)
return add_widget(project_id=project_id, user_id=user_id, dashboard_id=dashboard_id,
def create_metric_add_widget(project: schemas.ProjectContext, user_id, dashboard_id, data: schemas.CardSchema):
metric_id = custom_metrics.create_card(project=project, user_id=user_id, data=data, dashboard=True)
return add_widget(project_id=project.project_id, user_id=user_id, dashboard_id=dashboard_id,
data=schemas.AddWidgetToDashboardPayloadSchema(metricId=metric_id))
# def make_chart_widget(dashboard_id, project_id, user_id, widget_id, data: schemas.CardChartSchema):

View file

@ -102,7 +102,7 @@ def _search_tags(project_id, value, key=None, source=None):
with pg_client.PostgresClient() as cur:
query = f"""
SELECT public.tags.name
'{events.EventType.TAG.ui_type}' AS type
'TAG' AS type
FROM public.tags
WHERE public.tags.project_id = %(project_id)s
ORDER BY SIMILARITY(public.tags.name, %(value)s) DESC

View file

@ -1,11 +1,14 @@
import json
import logging
from typing import Any, List, Dict, Optional
import schemas
from chalicelib.utils import helper
from chalicelib.utils import pg_client
from chalicelib.utils.TimeUTC import TimeUTC
from typing import Any, List, Dict, Optional
from fastapi import HTTPException, status
import json
import logging
logger = logging.getLogger(__name__)
feature_flag_columns = (
"feature_flag_id",
@ -299,7 +302,8 @@ def create_conditions(feature_flag_id: int, conditions: List[schemas.FeatureFlag
with pg_client.PostgresClient() as cur:
params = [
(feature_flag_id, c.name, c.rollout_percentage, json.dumps([filter_.model_dump() for filter_ in c.filters]))
(feature_flag_id, c.name, c.rollout_percentage,
json.dumps([filter_.model_dump() for filter_ in c.filters]))
for c in conditions]
query = cur.mogrify(sql, params)
cur.execute(query)
@ -455,7 +459,8 @@ def create_variants(feature_flag_id: int, variants: List[schemas.FeatureFlagVari
"""
with pg_client.PostgresClient() as cur:
params = [(feature_flag_id, v.value, v.description, json.dumps(v.payload), v.rollout_percentage) for v in variants]
params = [(feature_flag_id, v.value, v.description, json.dumps(v.payload), v.rollout_percentage) for v in
variants]
query = cur.mogrify(sql, params)
cur.execute(query)
rows = cur.fetchall()

View file

@ -1,5 +1,4 @@
import logging
import math
import schemas
from chalicelib.core import metadata

View file

@ -1,14 +1,11 @@
from typing import List
import logging
from time import time
import schemas
from chalicelib.core import metadata
from chalicelib.core.metrics import __get_constraints, __get_constraint_values
from chalicelib.utils import helper, dev
from chalicelib.utils import helper
from chalicelib.utils import pg_client
from chalicelib.utils.TimeUTC import TimeUTC
from chalicelib.utils import sql_helper as sh
from time import time
import logging
logger = logging.getLogger(__name__)

View file

@ -1,13 +1,13 @@
import logging
from fastapi import HTTPException, status
from chalicelib.core import sessions, assist
from chalicelib.core.db_request_handler import DatabaseRequestHandler
from chalicelib.core.usability_testing.schema import UTTestCreate, UTTestSearch, UTTestUpdate
from chalicelib.utils.TimeUTC import TimeUTC
from chalicelib.utils.helper import dict_to_camel_case, list_to_camel_case
from fastapi import HTTPException, status
from chalicelib.core import sessions, assist
logger = logging.getLogger(__name__)
table_name = "ut_tests"

View file

@ -2,11 +2,12 @@ import logging
from typing import Optional
import requests
from fastapi import HTTPException, status
import schemas
from chalicelib.utils import pg_client, helper
from chalicelib.utils.TimeUTC import TimeUTC
from fastapi import HTTPException, status
logger = logging.getLogger(__name__)
def get_by_id(webhook_id):

View file

@ -67,7 +67,7 @@ def make_pool():
postgreSQL_pool = ORThreadedConnectionPool(config("PG_MINCONN", cast=int, default=4),
config("PG_MAXCONN", cast=int, default=8),
**PG_CONFIG)
if (postgreSQL_pool):
if postgreSQL_pool is not None:
logger.info("Connection pool created successfully")
except (Exception, psycopg2.DatabaseError) as error:
logger.error("Error while connecting to PostgreSQL", error)

View file

@ -1,9 +1,8 @@
from typing import Union
from fastapi import Body, Depends, Request
import schemas
from chalicelib.core import dashboards, custom_metrics, funnels
from chalicelib.core import dashboards, custom_metrics
from fastapi import Body, Depends
from or_dependencies import OR_context
from routers.base import get_routers
@ -60,7 +59,7 @@ def add_card_to_dashboard(projectId: int, dashboardId: int,
def create_metric_and_add_to_dashboard(projectId: int, dashboardId: int,
data: schemas.CardSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
return {"data": dashboards.create_metric_add_widget(project_id=projectId, user_id=context.user_id,
return {"data": dashboards.create_metric_add_widget(project=context.project, user_id=context.user_id,
dashboard_id=dashboardId, data=data)}
@ -82,7 +81,7 @@ def remove_widget_from_dashboard(projectId: int, dashboardId: int, widgetId: int
@app.post('/{projectId}/cards/try', tags=["cards"])
def try_card(projectId: int, data: schemas.CardSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
return {"data": custom_metrics.get_chart(project_id=projectId, data=data, user_id=context.user_id)}
return {"data": custom_metrics.get_chart(project=context.project, data=data, user_id=context.user_id)}
@app.post('/{projectId}/cards/try/sessions', tags=["cards"])
@ -106,7 +105,7 @@ def get_cards(projectId: int, context: schemas.CurrentContext = Depends(OR_conte
@app.post('/{projectId}/cards', tags=["cards"])
def create_card(projectId: int, data: schemas.CardSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
return custom_metrics.create_card(project_id=projectId, user_id=context.user_id, data=data)
return custom_metrics.create_card(project=context.project, user_id=context.user_id, data=data)
@app.post('/{projectId}/cards/search', tags=["cards"])

View file

@ -1,13 +1,11 @@
import hashlib
from decouple import config
import schemas
import schemas
from chalicelib.utils import pg_client, helper
from chalicelib.utils.TimeUTC import TimeUTC
from chalicelib.utils.storage import StorageClient
from chalicelib.utils.storage import extra
from decouple import config
def generate_file_key(project_id, key):

View file

@ -1,4 +1,3 @@
import chalicelib.utils.exp_ch_helper
import schemas
from chalicelib.core import countries, events, metadata
from chalicelib.utils import ch_client

View file

@ -256,14 +256,14 @@ def __get_path_analysis_card_info(data: schemas.CardPathAnalysis):
return r
def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=False):
def create_card(project: schemas.ProjectContext, user_id, data: schemas.CardSchema, dashboard=False):
with pg_client.PostgresClient() as cur:
session_data = None
if data.metric_type == schemas.MetricType.HEAT_MAP:
if data.session_id is not None:
session_data = {"sessionId": data.session_id}
else:
session_data = __get_heat_map_chart(project_id=project_id, user_id=user_id,
session_data = __get_heat_map_chart(project=project, user_id=user_id,
data=data, include_mobs=False)
if session_data is not None:
session_data = {"sessionId": session_data["sessionId"]}
@ -271,7 +271,7 @@ def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=False):
if session_data is not None:
# for EE only
keys = sessions_mobs. \
__get_mob_keys(project_id=project_id, session_id=session_data["sessionId"])
__get_mob_keys(project_id=project.project_id, session_id=session_data["sessionId"])
keys += sessions_mobs. \
__get_mob_keys_deprecated(session_id=session_data["sessionId"]) # To support old sessions
tag = config('RETENTION_L_VALUE', default='vault')
@ -289,7 +289,7 @@ def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=False):
_data[f"index_{i}"] = i
_data[f"filter_{i}"] = s.filter.json()
series_len = len(data.series)
params = {"user_id": user_id, "project_id": project_id, **data.model_dump(), **_data,
params = {"user_id": user_id, "project_id": project.project_id, **data.model_dump(), **_data,
"default_config": json.dumps(data.default_config.model_dump()), "card_info": None}
if data.metric_type == schemas.MetricType.PATH_ANALYSIS:
params["card_info"] = json.dumps(__get_path_analysis_card_info(data=data))
@ -315,7 +315,7 @@ def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=False):
r = cur.fetchone()
if dashboard:
return r["metric_id"]
return {"data": get_card(metric_id=r["metric_id"], project_id=project_id, user_id=user_id)}
return {"data": get_card(metric_id=r["metric_id"], project_id=project.project_id, user_id=user_id)}
def update_card(metric_id, user_id, project_id, data: schemas.CardSchema):

View file

@ -108,7 +108,7 @@ def _search_tags(project_id, value, key=None, source=None):
with pg_client.PostgresClient() as cur:
query = f"""
SELECT public.tags.name
'{events.EventType.TAG.ui_type}' AS type
'TAG' AS type
FROM public.tags
WHERE public.tags.project_id = %(project_id)s
ORDER BY SIMILARITY(public.tags.name, %(value)s) DESC

View file

@ -140,7 +140,7 @@ def search_sessions(data: schemas.SessionsSearchPayloadSchema, project_id, user_
MIN(full_sessions.start_ts) AS first_session_ts,
ROW_NUMBER() OVER (ORDER BY {g_sort} {data.order}) AS rn
FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY {sort} {data.order}) AS rn
FROM (SELECT DISTINCT ON(s.session_id) {SESSION_PROJECTION_COLS} {meta_map}
FROM (SELECT DISTINCT ON(s.session_id) {SESSION_PROJECTION_COLS_CH} {meta_map}
{query_part}
) AS filtred_sessions
) AS full_sessions
@ -294,7 +294,7 @@ def search2_series(data: schemas.SessionsSearchPayloadSchema, project_id: int, d
elif metric_of == schemas.MetricOfTable.USER_DEVICE:
main_col = "user_device"
extra_col = "s.user_device"
elif metric_of == schemas.MetricOfTable.user_browser:
elif metric_of == schemas.MetricOfTable.USER_BROWSER:
main_col = "user_browser"
extra_col = "s.user_browser"
elif metric_of == schemas.MetricOfTable.ISSUES:
@ -1564,7 +1564,7 @@ def search_by_metadata(tenant_id, user_id, m_key, m_value, project_id=None):
f"""(
SELECT *
FROM (
SELECT DISTINCT ON(favorite_sessions.session_id, s.session_id) {SESSION_PROJECTION_COLS}
SELECT DISTINCT ON(favorite_sessions.session_id, s.session_id) {SESSION_PROJECTION_COLS_CH}
FROM public.sessions AS s LEFT JOIN (SELECT session_id
FROM public.user_favorite_sessions
WHERE user_favorite_sessions.user_id = %(userId)s

View file

@ -1,9 +1,8 @@
from decouple import config
import schemas
from chalicelib.core import sessions, sessions_favorite_exp, sessions_mobs, sessions_devtool
from chalicelib.core import sessions_favorite_exp, sessions_mobs, sessions_devtool
from chalicelib.utils import pg_client
from chalicelib.utils.storage import extra
from decouple import config
def add_favorite_session(context: schemas.CurrentContext, project_id, session_id):

View file

@ -1,9 +1,8 @@
from typing import Union
from fastapi import Body, Depends, Request
import schemas
from chalicelib.core import dashboards, custom_metrics, funnels
from chalicelib.core import dashboards, custom_metrics
from fastapi import Body, Depends
from or_dependencies import OR_context, OR_scope
from routers.base import get_routers
@ -60,7 +59,7 @@ def add_card_to_dashboard(projectId: int, dashboardId: int,
def create_metric_and_add_to_dashboard(projectId: int, dashboardId: int,
data: schemas.CardSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
return {"data": dashboards.create_metric_add_widget(project_id=projectId, user_id=context.user_id,
return {"data": dashboards.create_metric_add_widget(project=context.project, user_id=context.user_id,
dashboard_id=dashboardId, data=data)}
@ -106,7 +105,7 @@ def get_cards(projectId: int, context: schemas.CurrentContext = Depends(OR_conte
@app.post('/{projectId}/cards', tags=["cards"])
def create_card(projectId: int, data: schemas.CardSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
return custom_metrics.create_card(project_id=projectId, user_id=context.user_id, data=data)
return custom_metrics.create_card(project=context.project, user_id=context.user_id, data=data)
@app.post('/{projectId}/cards/search', tags=["cards"])
@ -138,22 +137,6 @@ def get_card_sessions(projectId: int, metric_id: int,
return {"data": data}
@app.post('/{projectId}/cards/{metric_id}/issues', tags=["cards"])
def get_card_funnel_issues(projectId: int, metric_id: Union[int, str],
data: schemas.CardSessionsSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
if metric_id.isnumeric():
metric_id = int(metric_id)
else:
return {"errors": ["invalid card_id"]}
data = custom_metrics.get_funnel_issues(project_id=projectId, user_id=context.user_id, metric_id=metric_id,
data=data)
if data is None:
return {"errors": ["custom metric not found"]}
return {"data": data}
@app.post('/{projectId}/cards/{metric_id}/issues/{issueId}/sessions', tags=["dashboard"])
def get_metric_funnel_issue_sessions(projectId: int, metric_id: int, issueId: str,
data: schemas.CardSessionsSchema = Body(...),
@ -165,17 +148,6 @@ def get_metric_funnel_issue_sessions(projectId: int, metric_id: int, issueId: st
return {"data": data}
@app.post('/{projectId}/cards/{metric_id}/errors', tags=["dashboard"])
def get_card_errors_list(projectId: int, metric_id: int,
data: schemas.CardSessionsSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
data = custom_metrics.get_errors_list(project_id=projectId, user_id=context.user_id,
metric_id=metric_id, data=data)
if data is None:
return {"errors": ["custom metric not found"]}
return {"data": data}
@app.post('/{projectId}/cards/{metric_id}/chart', tags=["card"])
def get_card_chart(projectId: int, metric_id: int, data: schemas.CardSessionsSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):