From 94f14980873c02c923e17b0923440d8d3dae7c63 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Wed, 14 Dec 2022 16:32:34 +0100 Subject: [PATCH] feat(chalice): click-maps search for smallest session --- api/app.py | 3 +- api/chalicelib/core/click_maps.py | 74 ++++++ api/routers/core_dynamic.py | 7 +- api/routers/subs/dashboard.py | 398 ------------------------------ api/schemas.py | 24 +- 5 files changed, 104 insertions(+), 402 deletions(-) create mode 100644 api/chalicelib/core/click_maps.py delete mode 100644 api/routers/subs/dashboard.py diff --git a/api/app.py b/api/app.py index 26342484c..43c3b7945 100644 --- a/api/app.py +++ b/api/app.py @@ -12,7 +12,7 @@ from chalicelib.utils import pg_client from routers import core, core_dynamic from routers.crons import core_crons from routers.crons import core_dynamic_crons -from routers.subs import dashboard, insights, metrics, v1_api +from routers.subs import insights, metrics, v1_api app = FastAPI(root_path="/api", docs_url=config("docs_url", default=""), redoc_url=config("redoc_url", default="")) app.add_middleware(GZipMiddleware, minimum_size=1000) @@ -48,7 +48,6 @@ app.include_router(core.app_apikey) app.include_router(core_dynamic.public_app) app.include_router(core_dynamic.app) app.include_router(core_dynamic.app_apikey) -app.include_router(dashboard.app) app.include_router(metrics.app) app.include_router(insights.app) app.include_router(v1_api.app_apikey) diff --git a/api/chalicelib/core/click_maps.py b/api/chalicelib/core/click_maps.py new file mode 100644 index 000000000..0eed5bc6f --- /dev/null +++ b/api/chalicelib/core/click_maps.py @@ -0,0 +1,74 @@ +import schemas +from chalicelib.core import sessions_mobs, sessions as sessions_search +from chalicelib.utils import pg_client, helper + +SESSION_PROJECTION_COLS = """s.project_id, +s.session_id::text AS 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.start_ts, +s.duration, +s.events_count, +s.pages_count, +s.errors_count, +s.user_anonymous_id, +s.platform, +s.issue_score, +to_jsonb(s.issue_types) AS issue_types, +favorite_sessions.session_id NOTNULL AS favorite, +COALESCE((SELECT TRUE + FROM public.user_viewed_sessions AS fs + WHERE s.session_id = fs.session_id + AND fs.user_id = %(userId)s LIMIT 1), FALSE) AS viewed """ + + +def search_short_session(data: schemas.FlatClickMapSessionsSearch, project_id, user_id): + no_platform = True + for f in data.filters: + if f.type == schemas.FilterType.platform: + no_platform = False + break + if no_platform: + data.filters.append(schemas.SessionSearchFilterSchema(type=schemas.FilterType.platform, + value=[schemas.PlatformType.desktop], + operator=schemas.SearchEventOperator._is)) + + full_args, query_part = sessions_search.search_query_parts(data=data, error_status=None, errors_only=False, + favorite_only=data.bookmarked, issue=None, + project_id=project_id, user_id=user_id) + + with pg_client.PostgresClient() as cur: + data.order = schemas.SortOrderType.desc + data.sort = 'duration' + + # meta_keys = metadata.get(project_id=project_id) + meta_keys = [] + main_query = cur.mogrify(f"""SELECT {SESSION_PROJECTION_COLS} + {"," if len(meta_keys) > 0 else ""}{",".join([f'metadata_{m["index"]}' for m in meta_keys])} + {query_part} + ORDER BY {data.sort} {data.order} + LIMIT 1;""", full_args) + # print("--------------------") + # print(main_query) + # print("--------------------") + try: + cur.execute(main_query) + except Exception as err: + print("--------- CLICK MAP SHORT SESSION SEARCH QUERY EXCEPTION -----------") + print(main_query.decode('UTF-8')) + print("--------- PAYLOAD -----------") + print(data.json()) + print("--------------------") + raise err + + session = cur.fetchone() + if session: + session['domURL'] = sessions_mobs.get_urls(session_id=session["session_id"], project_id=project_id) + session['mobsUrl'] = sessions_mobs.get_urls_depercated(session_id=session["session_id"]) + + return helper.dict_to_camel_case(session) diff --git a/api/routers/core_dynamic.py b/api/routers/core_dynamic.py index fa351214c..7e716e772 100644 --- a/api/routers/core_dynamic.py +++ b/api/routers/core_dynamic.py @@ -6,7 +6,7 @@ from starlette.responses import RedirectResponse, FileResponse import schemas from chalicelib.core import sessions, errors, errors_viewed, errors_favorite, sessions_assignments, heatmaps, \ - sessions_favorite, assist, sessions_notes + sessions_favorite, assist, sessions_notes, click_maps from chalicelib.core import sessions_viewed from chalicelib.core import tenants, users, projects, license from chalicelib.core import webhook @@ -409,3 +409,8 @@ def get_all_notes(projectId: int, data: schemas.SearchNoteSchema = Body(...), if "errors" in data: return data return {'data': data} + +@app.post('/{projectId}/click_maps/search', tags=["savedSearch"]) +def click_map_search(projectId: int, data: schemas.FlatClickMapSessionsSearch = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): + return {"data": click_maps.search_short_session(user_id=context.user_id, data=data, project_id=projectId)} diff --git a/api/routers/subs/dashboard.py b/api/routers/subs/dashboard.py deleted file mode 100644 index d732191c2..000000000 --- a/api/routers/subs/dashboard.py +++ /dev/null @@ -1,398 +0,0 @@ -from fastapi import Body - -import schemas -from chalicelib.core import metrics -from chalicelib.core import metadata -from chalicelib.utils import helper -from routers.base import get_routers - -public_app, app, app_apikey = get_routers() - - -@app.get('/{projectId}/dashboard/metadata', tags=["dashboard", "metrics"]) -def get_metadata_map(projectId: int): - metamap = [] - for m in metadata.get(project_id=projectId): - metamap.append({"name": m["key"], "key": f"metadata{m['index']}"}) - return {"data": metamap} - - -@app.post('/{projectId}/dashboard/sessions', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/sessions', tags=["dashboard", "metrics"]) -def get_dashboard_processed_sessions(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_processed_sessions(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/errors', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/errors', tags=["dashboard", "metrics"]) -def get_dashboard_errors(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_errors(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/errors_trend', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/errors_trend', tags=["dashboard", "metrics"]) -def get_dashboard_errors_trend(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_errors_trend(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/application_activity', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/application_activity', tags=["dashboard", "metrics"]) -def get_dashboard_application_activity(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_application_activity(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/page_metrics', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/page_metrics', tags=["dashboard", "metrics"]) -def get_dashboard_page_metrics(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_page_metrics(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/user_activity', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/user_activity', tags=["dashboard", "metrics"]) -def get_dashboard_user_activity(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_user_activity(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/performance', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/performance', tags=["dashboard", "metrics"]) -def get_dashboard_performance(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_performance(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/slowest_images', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/slowest_images', tags=["dashboard", "metrics"]) -def get_dashboard_slowest_images(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_slowest_images(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/missing_resources', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/missing_resources', tags=["dashboard", "metrics"]) -def get_performance_sessions(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_missing_resources_trend(project_id=projectId, **data.dict())} - - -@app.post('/{projectId}/dashboard/network', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/network', tags=["dashboard", "metrics"]) -def get_network_widget(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_network(project_id=projectId, **data.dict())} - - -@app.get('/{projectId}/dashboard/{widget}/search', tags=["dashboard", "metrics"]) -def get_dashboard_autocomplete(projectId: int, widget: str, q: str, type: str = "", platform: str = None, - key: str = ""): - if q is None or len(q) == 0: - return {"data": []} - q = '^' + q - - if widget in ['performance']: - data = metrics.search(q, type, project_id=projectId, - platform=platform, performance=True) - elif widget in ['pages', 'pages_dom_buildtime', 'top_metrics', 'time_to_render', - 'impacted_sessions_by_slow_pages', 'pages_response_time']: - data = metrics.search(q, type, project_id=projectId, - platform=platform, pages_only=True) - elif widget in ['resources_loading_time']: - data = metrics.search(q, type, project_id=projectId, - platform=platform, performance=False) - elif widget in ['time_between_events', 'events']: - data = metrics.search(q, type, project_id=projectId, - platform=platform, performance=False, events_only=True) - elif widget in ['metadata']: - data = metrics.search(q, None, project_id=projectId, - platform=platform, metadata=True, key=key) - else: - return {"errors": [f"unsupported widget: {widget}"]} - return {'data': data} - - -# 1 -@app.post('/{projectId}/dashboard/slowest_resources', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/slowest_resources', tags=["dashboard", "metrics"]) -def get_dashboard_slowest_resources(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_slowest_resources(project_id=projectId, **data.dict())} - - -# 2 -@app.post('/{projectId}/dashboard/resources_loading_time', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/resources_loading_time', tags=["dashboard", "metrics"]) -def get_dashboard_resources(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_resources_loading_time(project_id=projectId, **data.dict())} - - -# 3 -@app.post('/{projectId}/dashboard/pages_dom_buildtime', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/pages_dom_buildtime', tags=["dashboard", "metrics"]) -def get_dashboard_pages_dom(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_pages_dom_build_time(project_id=projectId, **data.dict())} - - -# 4 -@app.post('/{projectId}/dashboard/busiest_time_of_day', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/busiest_time_of_day', tags=["dashboard", "metrics"]) -def get_dashboard_busiest_time_of_day(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_busiest_time_of_day(project_id=projectId, **data.dict())} - - -# 5 -@app.post('/{projectId}/dashboard/sessions_location', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/sessions_location', tags=["dashboard", "metrics"]) -def get_dashboard_sessions_location(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_sessions_location(project_id=projectId, **data.dict())} - - -# 6 -@app.post('/{projectId}/dashboard/speed_location', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/speed_location', tags=["dashboard", "metrics"]) -def get_dashboard_speed_location(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_speed_index_location(project_id=projectId, **data.dict())} - - -# 7 -@app.post('/{projectId}/dashboard/pages_response_time', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/pages_response_time', tags=["dashboard", "metrics"]) -def get_dashboard_pages_response_time(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_pages_response_time(project_id=projectId, **data.dict())} - - -# 8 -@app.post('/{projectId}/dashboard/pages_response_time_distribution', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/pages_response_time_distribution', tags=["dashboard", "metrics"]) -def get_dashboard_pages_response_time_distribution(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_pages_response_time_distribution(project_id=projectId, **data.dict())} - - -# 9 -@app.post('/{projectId}/dashboard/top_metrics', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/top_metrics', tags=["dashboard", "metrics"]) -def get_dashboard_top_metrics(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_top_metrics(project_id=projectId, **data.dict())} - - -# 10 -@app.post('/{projectId}/dashboard/time_to_render', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/time_to_render', tags=["dashboard", "metrics"]) -def get_dashboard_time_to_render(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_time_to_render(project_id=projectId, **data.dict())} - - -# 11 -@app.post('/{projectId}/dashboard/impacted_sessions_by_slow_pages', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/impacted_sessions_by_slow_pages', tags=["dashboard", "metrics"]) -def get_dashboard_impacted_sessions_by_slow_pages(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_impacted_sessions_by_slow_pages(project_id=projectId, **data.dict())} - - -# 12 -@app.post('/{projectId}/dashboard/memory_consumption', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/memory_consumption', tags=["dashboard", "metrics"]) -def get_dashboard_memory_consumption(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_memory_consumption(project_id=projectId, **data.dict())} - - -# 12.1 -@app.post('/{projectId}/dashboard/fps', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/fps', tags=["dashboard", "metrics"]) -def get_dashboard_avg_fps(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_avg_fps(project_id=projectId, **data.dict())} - - -# 12.2 -@app.post('/{projectId}/dashboard/cpu', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/cpu', tags=["dashboard", "metrics"]) -def get_dashboard_avg_cpu(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_avg_cpu(project_id=projectId, **data.dict())} - - -# 13 -@app.post('/{projectId}/dashboard/crashes', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/crashes', tags=["dashboard", "metrics"]) -def get_dashboard_impacted_sessions_by_slow_pages(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_crashes(project_id=projectId, **data.dict())} - - -# 14 -@app.post('/{projectId}/dashboard/domains_errors', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/domains_errors', tags=["dashboard", "metrics"]) -def get_dashboard_domains_errors(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_domains_errors(project_id=projectId, **data.dict())} - - -# 14.1 -@app.post('/{projectId}/dashboard/domains_errors_4xx', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/domains_errors_4xx', tags=["dashboard", "metrics"]) -def get_dashboard_domains_errors_4xx(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_domains_errors_4xx(project_id=projectId, **data.dict())} - - -# 14.2 -@app.post('/{projectId}/dashboard/domains_errors_5xx', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/domains_errors_5xx', tags=["dashboard", "metrics"]) -def get_dashboard_domains_errors_5xx(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_domains_errors_5xx(project_id=projectId, **data.dict())} - - -# 15 -@app.post('/{projectId}/dashboard/slowest_domains', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/slowest_domains', tags=["dashboard", "metrics"]) -def get_dashboard_slowest_domains(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_slowest_domains(project_id=projectId, **data.dict())} - - -# 16 -@app.post('/{projectId}/dashboard/errors_per_domains', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/errors_per_domains', tags=["dashboard", "metrics"]) -def get_dashboard_errors_per_domains(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_errors_per_domains(project_id=projectId, **data.dict())} - - -# 17 -@app.post('/{projectId}/dashboard/sessions_per_browser', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/sessions_per_browser', tags=["dashboard", "metrics"]) -def get_dashboard_sessions_per_browser(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_sessions_per_browser(project_id=projectId, **data.dict())} - - -# 18 -@app.post('/{projectId}/dashboard/calls_errors', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/calls_errors', tags=["dashboard", "metrics"]) -def get_dashboard_calls_errors(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_calls_errors(project_id=projectId, **data.dict())} - - -# 18.1 -@app.post('/{projectId}/dashboard/calls_errors_4xx', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/calls_errors_4xx', tags=["dashboard", "metrics"]) -def get_dashboard_calls_errors_4xx(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_calls_errors_4xx(project_id=projectId, **data.dict())} - - -# 18.2 -@app.post('/{projectId}/dashboard/calls_errors_5xx', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/calls_errors_5xx', tags=["dashboard", "metrics"]) -def get_dashboard_calls_errors_5xx(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_calls_errors_5xx(project_id=projectId, **data.dict())} - - -# 19 -@app.post('/{projectId}/dashboard/errors_per_type', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/errors_per_type', tags=["dashboard", "metrics"]) -def get_dashboard_errors_per_type(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_errors_per_type(project_id=projectId, **data.dict())} - - -# 20 -@app.post('/{projectId}/dashboard/resources_by_party', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/resources_by_party', tags=["dashboard", "metrics"]) -def get_dashboard_resources_by_party(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_resources_by_party(project_id=projectId, **data.dict())} - - -# 21 -@app.post('/{projectId}/dashboard/resource_type_vs_response_end', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/resource_type_vs_response_end', tags=["dashboard", "metrics"]) -def get_dashboard_errors_per_resource_type(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.resource_type_vs_response_end(project_id=projectId, **data.dict())} - - -# 22 -@app.post('/{projectId}/dashboard/resources_vs_visually_complete', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/resources_vs_visually_complete', tags=["dashboard", "metrics"]) -def get_dashboard_resources_vs_visually_complete(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_resources_vs_visually_complete(project_id=projectId, **data.dict())} - - -# 23 -@app.post('/{projectId}/dashboard/impacted_sessions_by_js_errors', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/impacted_sessions_by_js_errors', tags=["dashboard", "metrics"]) -def get_dashboard_impacted_sessions_by_js_errors(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_impacted_sessions_by_js_errors(project_id=projectId, **data.dict())} - - -# 24 -@app.post('/{projectId}/dashboard/resources_count_by_type', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/resources_count_by_type', tags=["dashboard", "metrics"]) -def get_dashboard_resources_count_by_type(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - return {"data": metrics.get_resources_count_by_type(project_id=projectId, **data.dict())} - - -# # 25 -# @app.post('/{projectId}/dashboard/time_between_events', tags=["dashboard", "metrics"]) -# @app.get('/{projectId}/dashboard/time_between_events', tags=["dashboard", "metrics"]) -# def get_dashboard_resources_count_by_type(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): -# return {"errors": ["please choose 2 events"]} - - -@app.post('/{projectId}/dashboard/overview', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/overview', tags=["dashboard", "metrics"]) -def get_dashboard_group(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - results = [ - {"key": "count_sessions", - "data": metrics.get_processed_sessions(project_id=projectId, **data.dict())}, - *helper.explode_widget(data={**metrics.get_application_activity(project_id=projectId, **data.dict()), - "chart": metrics.get_performance(project_id=projectId, **data.dict()) - .get("chart", [])}), - *helper.explode_widget(data=metrics.get_page_metrics(project_id=projectId, **data.dict())), - *helper.explode_widget(data=metrics.get_user_activity(project_id=projectId, **data.dict())), - {"key": "avg_pages_dom_buildtime", - "data": metrics.get_pages_dom_build_time(project_id=projectId, **data.dict())}, - {"key": "avg_pages_response_time", - "data": metrics.get_pages_response_time(project_id=projectId, **data.dict()) - }, - *helper.explode_widget(metrics.get_top_metrics(project_id=projectId, **data.dict())), - {"key": "avg_time_to_render", "data": metrics.get_time_to_render(project_id=projectId, **data.dict())}, - {"key": "avg_used_js_heap_size", "data": metrics.get_memory_consumption(project_id=projectId, **data.dict())}, - {"key": "avg_cpu", "data": metrics.get_avg_cpu(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_fps, - "data": metrics.get_avg_fps(project_id=projectId, **data.dict())} - ] - results = sorted(results, key=lambda r: r["key"]) - return {"data": results} - - -@app.post('/{projectId}/dashboard/overview2', tags=["dashboard", "metrics"]) -@app.get('/{projectId}/dashboard/overview2', tags=["dashboard", "metrics"]) -def get_dashboard_group(projectId: int, data: schemas.MetricPayloadSchema = Body(...)): - results = [ - {"key": schemas.MetricOfWebVitals.count_sessions, - "data": metrics.get_processed_sessions(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_image_load_time, - "data": metrics.get_application_activity_avg_image_load_time(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_page_load_time, - "data": metrics.get_application_activity_avg_page_load_time(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_request_load_time, - "data": metrics.get_application_activity_avg_request_load_time(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_dom_content_load_start, - "data": metrics.get_page_metrics_avg_dom_content_load_start(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_first_contentful_pixel, - "data": metrics.get_page_metrics_avg_first_contentful_pixel(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_visited_pages, - "data": metrics.get_user_activity_avg_visited_pages(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_session_duration, - "data": metrics.get_user_activity_avg_session_duration(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_pages_dom_buildtime, - "data": metrics.get_pages_dom_build_time(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_pages_response_time, - "data": metrics.get_pages_response_time(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_response_time, - "data": metrics.get_top_metrics_avg_response_time(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_first_paint, - "data": metrics.get_top_metrics_avg_first_paint(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_dom_content_loaded, - "data": metrics.get_top_metrics_avg_dom_content_loaded(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_till_first_byte, - "data": metrics.get_top_metrics_avg_till_first_bit(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_time_to_interactive, - "data": metrics.get_top_metrics_avg_time_to_interactive(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.count_requests, - "data": metrics.get_top_metrics_count_requests(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_time_to_render, - "data": metrics.get_time_to_render(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_used_js_heap_size, - "data": metrics.get_memory_consumption(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_cpu, - "data": metrics.get_avg_cpu(project_id=projectId, **data.dict())}, - {"key": schemas.MetricOfWebVitals.avg_fps, - "data": metrics.get_avg_fps(project_id=projectId, **data.dict())} - ] - results = sorted(results, key=lambda r: r["key"]) - return {"data": results} diff --git a/api/schemas.py b/api/schemas.py index 718628760..f0d4b4be7 100644 --- a/api/schemas.py +++ b/api/schemas.py @@ -913,7 +913,7 @@ class CreateCardSchema(CardChartSchema): metric_type: MetricType = Field(default=MetricType.timeseries) metric_of: Union[MetricOfTimeseries, MetricOfTable, MetricOfErrors, \ MetricOfPerformance, MetricOfResources, MetricOfWebVitals] = Field(MetricOfTable.user_id) - metric_value: List[IssueType] = Field([]) + metric_value: List[IssueType] = Field(default=[]) metric_format: Optional[MetricFormatType] = Field(None) default_config: CardConfigSchema = Field(..., alias="config") is_template: bool = Field(default=False) @@ -1168,3 +1168,25 @@ class SearchCardsSchema(_PaginatedSchema): class Config: alias_generator = attribute_to_camel_case + + +class _ClickMapSearchEventRaw(_SessionSearchEventRaw): + type: Literal[EventType.location] = Field(...) + + +class FlatClickMapSessionsSearch(SessionsSearchPayloadSchema): + events: Optional[List[_ClickMapSearchEventRaw]] = Field([]) + filters: List[Union[SessionSearchFilterSchema, _ClickMapSearchEventRaw]] = Field([]) + + @root_validator() + def flat_to_original(cls, values): + n_filters = [] + n_events = [] + for v in values.get("filters", []): + if isinstance(v, _ClickMapSearchEventRaw): + n_events.append(v) + else: + n_filters.append(v) + values["events"] = n_events + values["filters"] = n_filters + return values