From 66040ea9f5cfe71aab99de88b5d4f9628722c4f0 Mon Sep 17 00:00:00 2001 From: Amirouche Date: Thu, 1 Feb 2024 09:30:54 +0100 Subject: [PATCH] wip --- api/auth/auth_jwt.py | 6 +- api/chalicelib/core/alerts.py | 2 +- api/chalicelib/core/assist.py | 2 +- api/chalicelib/core/autocomplete.py | 4 +- api/chalicelib/core/collaboration_slack.py | 6 +- api/chalicelib/core/custom_metrics.py | 134 +++++----- api/chalicelib/core/dashboards.py | 2 +- api/chalicelib/core/db_request_handler.py | 10 +- api/chalicelib/core/errors.py | 2 +- api/chalicelib/core/integration_base.py | 7 +- api/chalicelib/utils/captcha.py | 2 +- api/chalicelib/utils/pg_client.py | 4 +- api/routers/core.py | 270 ++++++++++----------- api/routers/core_dynamic.py | 114 ++++----- 14 files changed, 283 insertions(+), 282 deletions(-) diff --git a/api/auth/auth_jwt.py b/api/auth/auth_jwt.py index 24029b84c..1fefc9b75 100644 --- a/api/auth/auth_jwt.py +++ b/api/auth/auth_jwt.py @@ -53,7 +53,7 @@ class JWTAuth(HTTPBearer): or old_jwt_payload.get("userId") != jwt_payload.get("userId"): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Invalid token or expired token.") - return _get_current_auth_context(request=request, jwt_payload=jwt_payload) + return await _get_current_auth_context(request=request, jwt_payload=jwt_payload) else: credentials: HTTPAuthorizationCredentials = await super(JWTAuth, self).__call__(request) @@ -63,7 +63,7 @@ class JWTAuth(HTTPBearer): detail="Invalid authentication scheme.") jwt_payload = authorizers.jwt_authorizer(scheme=credentials.scheme, token=credentials.credentials) auth_exists = jwt_payload is not None \ - and users.auth_exists(user_id=jwt_payload.get("userId", -1), + and await users.auth_exists(user_id=jwt_payload.get("userId", -1), jwt_iat=jwt_payload.get("iat", 100)) if jwt_payload is None \ or jwt_payload.get("iat") is None or jwt_payload.get("aud") is None \ @@ -79,7 +79,7 @@ class JWTAuth(HTTPBearer): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Invalid token or expired token.") - return _get_current_auth_context(request=request, jwt_payload=jwt_payload) + return await _get_current_auth_context(request=request, jwt_payload=jwt_payload) logger.warning("Invalid authorization code.") raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid authorization code.") diff --git a/api/chalicelib/core/alerts.py b/api/chalicelib/core/alerts.py index 2f21482bd..78f5ce4d6 100644 --- a/api/chalicelib/core/alerts.py +++ b/api/chalicelib/core/alerts.py @@ -211,7 +211,7 @@ async def send_to_msteams_batch(notifications_list): async def delete(project_id, alert_id): - with pg_client.cursor() as cur: + async with pg_client.cursor() as cur: await cur.execute( cur.mogrify(""" UPDATE public.alerts SET deleted_at = timezone('utc'::text, now()), diff --git a/api/chalicelib/core/assist.py b/api/chalicelib/core/assist.py index 85ae87a21..56c267a4c 100644 --- a/api/chalicelib/core/assist.py +++ b/api/chalicelib/core/assist.py @@ -61,7 +61,7 @@ async def get_live_sessions_ws(project_id, body: schemas.LiveSessionsSearchPaylo async def __get_live_sessions_ws(project_id, data): - project_key = projects.get_project_key(project_id) + project_key = await projects.get_project_key(project_id) try: async with httpx.AsyncClient() as client: results = await client.post(ASSIST_URL + config("assist") + f"/{project_key}", diff --git a/api/chalicelib/core/autocomplete.py b/api/chalicelib/core/autocomplete.py index 68a287543..c20d0ecf5 100644 --- a/api/chalicelib/core/autocomplete.py +++ b/api/chalicelib/core/autocomplete.py @@ -1,4 +1,4 @@ -import schemas +.import schemas from chalicelib.core import countries, events, metadata from chalicelib.utils import helper from chalicelib.utils import pg_client @@ -295,7 +295,7 @@ async def __search_errors_ios(project_id, value, key=None, source=None): async def __search_metadata(project_id, value, key=None, source=None): - meta_keys = metadata.get(project_id=project_id) + meta_keys = await metadata.get(project_id=project_id) meta_keys = {m["key"]: m["index"] for m in meta_keys} if len(meta_keys) == 0 or key is not None and key not in meta_keys.keys(): return [] diff --git a/api/chalicelib/core/collaboration_slack.py b/api/chalicelib/core/collaboration_slack.py index 3c96d42df..98d476472 100644 --- a/api/chalicelib/core/collaboration_slack.py +++ b/api/chalicelib/core/collaboration_slack.py @@ -12,11 +12,11 @@ from chalicelib.core.collaboration_base import BaseCollaboration class Slack(BaseCollaboration): @classmethod async def add(cls, tenant_id, data: schemas.AddCollaborationSchema): - if webhook.exists_by_name(tenant_id=tenant_id, name=data.name, exclude_id=None, + if await webhook.exists_by_name(tenant_id=tenant_id, name=data.name, exclude_id=None, webhook_type=schemas.WebhookType.slack): raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"name already exists.") if cls.say_hello(data.url): - return webhook.add(tenant_id=tenant_id, + return await webhook.add(tenant_id=tenant_id, endpoint=data.url.unicode_string(), webhook_type=schemas.WebhookType.slack, name=data.name) @@ -118,7 +118,7 @@ class Slack(BaseCollaboration): @classmethod async def get_integration(cls, tenant_id, integration_id=None): if integration_id is not None: - return webhook.get_webhook(tenant_id=tenant_id, webhook_id=integration_id, + return await webhook.get_webhook(tenant_id=tenant_id, webhook_id=integration_id, webhook_type=schemas.WebhookType.slack) integrations = await webhook.get_by_type(tenant_id=tenant_id, webhook_type=schemas.WebhookType.slack) diff --git a/api/chalicelib/core/custom_metrics.py b/api/chalicelib/core/custom_metrics.py index ae9a3b695..f189bf8b2 100644 --- a/api/chalicelib/core/custom_metrics.py +++ b/api/chalicelib/core/custom_metrics.py @@ -57,55 +57,55 @@ async def __get_table_of_series(project_id, data: schemas.CardSchema): return results -def __get_funnel_chart(project_id: int, data: schemas.CardFunnel, user_id: int = None): +async def __get_funnel_chart(project_id: int, data: schemas.CardFunnel, user_id: int = None): if len(data.series) == 0: return { "stages": [], "totalDropDueToIssues": 0 } - return funnels.get_top_insights_on_the_fly_widget(project_id=project_id, data=data.series[0].filter) + return await funnels.get_top_insights_on_the_fly_widget(project_id=project_id, data=data.series[0].filter) -def __get_errors_list(project_id, user_id, data: schemas.CardSchema): +async def __get_errors_list(project_id, user_id, data: schemas.CardSchema): if len(data.series) == 0: return { "total": 0, "errors": [] } - return errors.search(data.series[0].filter, project_id=project_id, user_id=user_id) + return await errors.search(data.series[0].filter, project_id=project_id, user_id=user_id) -def __get_sessions_list(project_id, user_id, data: schemas.CardSchema): +async def __get_sessions_list(project_id, user_id, data: schemas.CardSchema): if len(data.series) == 0: logger.debug("empty series") return { "total": 0, "sessions": [] } - return sessions.search_sessions(data=data.series[0].filter, project_id=project_id, user_id=user_id) + return await sessions.search_sessions(data=data.series[0].filter, project_id=project_id, user_id=user_id) -def __get_click_map_chart(project_id, user_id, data: schemas.CardClickMap, include_mobs: bool = True): +async def __get_click_map_chart(project_id, user_id, data: schemas.CardClickMap, include_mobs: bool = True): if len(data.series) == 0: return None - return click_maps.search_short_session(project_id=project_id, user_id=user_id, + return await click_maps.search_short_session(project_id=project_id, user_id=user_id, 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): +async def __get_path_analysis_chart(project_id: int, user_id: int, data: schemas.CardPathAnalysis): if len(data.series) == 0: data.series.append( schemas.CardPathAnalysisSeriesSchema(startTimestamp=data.startTimestamp, endTimestamp=data.endTimestamp)) elif not isinstance(data.series[0].filter, schemas.PathAnalysisSchema): data.series[0].filter = schemas.PathAnalysisSchema() - return product_analytics.path_analysis(project_id=project_id, data=data) + return await product_analytics.path_analysis(project_id=project_id, data=data) -def __get_timeseries_chart(project_id: int, data: schemas.CardTimeSeries, user_id: int = None): - series_charts = __try_live(project_id=project_id, data=data) +async def __get_timeseries_chart(project_id: int, data: schemas.CardTimeSeries, user_id: int = None): + series_charts = await __try_live(project_id=project_id, data=data) if data.view_type == schemas.MetricTimeseriesViewType.progress: return series_charts results = [{}] * len(series_charts[0]) @@ -120,39 +120,39 @@ def not_supported(**args): raise Exception("not supported") -def __get_table_of_user_ids(project_id: int, data: schemas.CardTable, user_id: int = None): - return __get_table_of_series(project_id=project_id, data=data) +async def __get_table_of_user_ids(project_id: int, data: schemas.CardTable, user_id: int = None): + return await __get_table_of_series(project_id=project_id, data=data) -def __get_table_of_sessions(project_id: int, data: schemas.CardTable, user_id): - return __get_sessions_list(project_id=project_id, user_id=user_id, data=data) +async def __get_table_of_sessions(project_id: int, data: schemas.CardTable, user_id): + return await __get_sessions_list(project_id=project_id, user_id=user_id, data=data) -def __get_table_of_errors(project_id: int, data: schemas.CardTable, user_id: int): - return __get_errors_list(project_id=project_id, user_id=user_id, data=data) +async def __get_table_of_errors(project_id: int, data: schemas.CardTable, user_id: int): + return await __get_errors_list(project_id=project_id, user_id=user_id, data=data) -def __get_table_of_issues(project_id: int, data: schemas.CardTable, user_id: int = None): - return __get_table_of_series(project_id=project_id, data=data) +async def __get_table_of_issues(project_id: int, data: schemas.CardTable, user_id: int = None): + return await __get_table_of_series(project_id=project_id, data=data) -def __get_table_of_browsers(project_id: int, data: schemas.CardTable, user_id: int = None): - return __get_table_of_series(project_id=project_id, data=data) +async def __get_table_of_browsers(project_id: int, data: schemas.CardTable, user_id: int = None): + return await __get_table_of_series(project_id=project_id, data=data) -def __get_table_of_devises(project_id: int, data: schemas.CardTable, user_id: int = None): - return __get_table_of_series(project_id=project_id, data=data) +async def __get_table_of_devises(project_id: int, data: schemas.CardTable, user_id: int = None): + return await __get_table_of_series(project_id=project_id, data=data) -def __get_table_of_countries(project_id: int, data: schemas.CardTable, user_id: int = None): - return __get_table_of_series(project_id=project_id, data=data) +async def __get_table_of_countries(project_id: int, data: schemas.CardTable, user_id: int = None): + return await __get_table_of_series(project_id=project_id, data=data) -def __get_table_of_urls(project_id: int, data: schemas.CardTable, user_id: int = None): - return __get_table_of_series(project_id=project_id, data=data) +async ef __get_table_of_urls(project_id: int, data: schemas.CardTable, user_id: int = None): + return await __get_table_of_series(project_id=project_id, data=data) -def __get_table_chart(project_id: int, data: schemas.CardTable, user_id: int): +async def __get_table_chart(project_id: int, data: schemas.CardTable, user_id: int): supported = { schemas.MetricOfTable.sessions: __get_table_of_sessions, schemas.MetricOfTable.errors: __get_table_of_errors, @@ -163,12 +163,12 @@ def __get_table_chart(project_id: int, data: schemas.CardTable, user_id: int): schemas.MetricOfTable.user_country: __get_table_of_countries, schemas.MetricOfTable.visited_url: __get_table_of_urls, } - return supported.get(data.metric_of, not_supported)(project_id=project_id, data=data, user_id=user_id) + return await supported.get(data.metric_of, not_supported)(project_id=project_id, data=data, user_id=user_id) -def get_chart(project_id: int, data: schemas.CardSchema, user_id: int): +async def get_chart(project_id: int, data: schemas.CardSchema, user_id: int): if data.is_predefined: - return custom_metrics_predefined.get_metric(key=data.metric_of, + return await custom_metrics_predefined.get_metric(key=data.metric_of, project_id=project_id, data=data.model_dump()) @@ -180,7 +180,7 @@ def get_chart(project_id: int, data: schemas.CardSchema, user_id: int): schemas.MetricType.insights: not_supported, schemas.MetricType.pathAnalysis: __get_path_analysis_chart } - return supported.get(data.metric_type, not_supported)(project_id=project_id, data=data, user_id=user_id) + return await supported.get(data.metric_type, not_supported)(project_id=project_id, data=data, user_id=user_id) def __merge_metric_with_data(metric: schemas.CardSchema, @@ -200,8 +200,8 @@ def __merge_metric_with_data(metric: schemas.CardSchema, return metric -def get_sessions_by_card_id(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): - card: dict = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) +async def get_sessions_by_card_id(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): + card: dict = await get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) if card is None: return None metric: schemas.CardSchema = schemas.CardSchema(**card) @@ -209,13 +209,13 @@ def get_sessions_by_card_id(project_id, user_id, metric_id, data: schemas.CardSe results = [] for s in metric.series: results.append({"seriesId": s.series_id, "seriesName": s.name, - **sessions.search_sessions(data=s.filter, project_id=project_id, user_id=user_id)}) + **await sessions.search_sessions(data=s.filter, project_id=project_id, user_id=user_id)}) return results -def get_funnel_issues(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): - raw_metric: dict = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) +async def get_funnel_issues(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): + raw_metric: dict = await 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.CardSchema = schemas.CardSchema(**raw_metric) @@ -224,11 +224,11 @@ def get_funnel_issues(project_id, user_id, metric_id, data: schemas.CardSessions return None for s in metric.series: return {"seriesId": s.series_id, "seriesName": s.name, - **funnels.get_issues_on_the_fly_widget(project_id=project_id, data=s.filter)} + **await funnels.get_issues_on_the_fly_widget(project_id=project_id, data=s.filter)} -def get_errors_list(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): - raw_metric: dict = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) +async def get_errors_list(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): + raw_metric: dict = await 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.CardSchema = schemas.CardSchema(**raw_metric) @@ -237,10 +237,10 @@ def get_errors_list(project_id, user_id, metric_id, data: schemas.CardSessionsSc return None for s in metric.series: return {"seriesId": s.series_id, "seriesName": s.name, - **errors.search(data=s.filter, project_id=project_id, user_id=user_id)} + **await errors.search(data=s.filter, project_id=project_id, user_id=user_id)} -def get_sessions(project_id, user_id, data: schemas.CardSessionsSchema): +async def get_sessions(project_id, user_id, data: schemas.CardSessionsSchema): results = [] if len(data.series) == 0: return results @@ -250,21 +250,21 @@ def get_sessions(project_id, user_id, data: schemas.CardSessionsSchema): s.filter = schemas.SessionsSearchPayloadSchema(**s.filter.model_dump(by_alias=True)) results.append({"seriesId": None, "seriesName": s.name, - **sessions.search_sessions(data=s.filter, project_id=project_id, user_id=user_id)}) + **await sessions.search_sessions(data=s.filter, project_id=project_id, user_id=user_id)}) return results -def __get_funnel_issues(project_id: int, user_id: int, data: schemas.CardFunnel): +async def __get_funnel_issues(project_id: int, user_id: int, data: schemas.CardFunnel): if len(data.series) == 0: return {"data": []} data.series[0].filter.startTimestamp = data.startTimestamp data.series[0].filter.endTimestamp = data.endTimestamp - data = funnels.get_issues_on_the_fly_widget(project_id=project_id, data=data.series[0].filter) + data = await funnels.get_issues_on_the_fly_widget(project_id=project_id, data=data.series[0].filter) return {"data": data} -def __get_path_analysis_issues(project_id: int, user_id: int, data: schemas.CardPathAnalysis): +async def __get_path_analysis_issues(project_id: int, user_id: int, data: schemas.CardPathAnalysis): if len(data.filters) > 0 or len(data.series) > 0: filters = [f.model_dump(by_alias=True) for f in data.filters] \ + [f.model_dump(by_alias=True) for f in data.series[0].filter.filters] @@ -283,15 +283,15 @@ def __get_path_analysis_issues(project_id: int, user_id: int, data: schemas.Card search_data.filters.append(schemas.SessionSearchEventSchema2(type=s.type, operator=schemas.SearchEventOperator._not_on, value=s.value)) - result = sessions.search_table_of_individual_issues(project_id=project_id, data=search_data) + result = await sessions.search_table_of_individual_issues(project_id=project_id, data=search_data) return result -def get_issues(project_id: int, user_id: int, data: schemas.CardSchema): +async def get_issues(project_id: int, user_id: int, data: schemas.CardSchema): if data.is_predefined: return not_supported() if data.metric_of == schemas.MetricOfTable.issues: - return __get_table_of_issues(project_id=project_id, user_id=user_id, data=data) + return await __get_table_of_issues(project_id=project_id, user_id=user_id, data=data) supported = { schemas.MetricType.timeseries: not_supported, schemas.MetricType.table: not_supported, @@ -300,7 +300,7 @@ def get_issues(project_id: int, user_id: int, data: schemas.CardSchema): schemas.MetricType.insights: not_supported, schemas.MetricType.pathAnalysis: __get_path_analysis_issues, } - return supported.get(data.metric_type, not_supported)(project_id=project_id, data=data, user_id=user_id) + return await supported.get(data.metric_type, not_supported)(project_id=project_id, data=data, user_id=user_id) def __get_path_analysis_card_info(data: schemas.CardPathAnalysis): @@ -315,7 +315,7 @@ async def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=F async with pg_client.cursor() as cur: session_data = None if data.metric_type == schemas.MetricType.click_map: - session_data = __get_click_map_chart(project_id=project_id, user_id=user_id, + session_data = await __get_click_map_chart(project_id=project_id, user_id=user_id, data=data, include_mobs=False) if session_data is not None: session_data = json.dumps(session_data) @@ -330,7 +330,7 @@ async def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=F params["default_config"] = json.dumps(data.default_config.model_dump()) params["card_info"] = None if data.metric_type == schemas.MetricType.pathAnalysis: - params["card_info"] = json.dumps(__get_path_analysis_card_info(data=data)) + params["card_info"] = json.dumps(await __get_path_analysis_card_info(data=data)) query = """INSERT INTO metrics (project_id, user_id, name, is_public, view_type, metric_type, metric_of, metric_value, @@ -353,11 +353,11 @@ async def create_card(project_id, user_id, data: schemas.CardSchema, dashboard=F r = await 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": await get_card(metric_id=r["metric_id"], project_id=project_id, user_id=user_id)} async def update_card(metric_id, user_id, project_id, data: schemas.CardSchema): - metric: dict = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) + metric: dict = await get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) if metric is None: return None series_ids = [r["seriesId"] for r in metric["series"]] @@ -391,7 +391,7 @@ async def update_card(metric_id, user_id, project_id, data: schemas.CardSchema): params["d_series_ids"] = tuple(d_series_ids) params["card_info"] = None if data.metric_type == schemas.MetricType.pathAnalysis: - params["card_info"] = json.dumps(__get_path_analysis_card_info(data=data)) + params["card_info"] = json.dumps(await __get_path_analysis_card_info(data=data)) async with pg_client.cursor() as cur: sub_queries = [] @@ -431,7 +431,7 @@ async def update_card(metric_id, user_id, project_id, data: schemas.CardSchema): AND (user_id = %(user_id)s OR is_public) RETURNING metric_id;""", params) await cur.execute(query) - return get_card(metric_id=metric_id, project_id=project_id, user_id=user_id) + return await get_card(metric_id=metric_id, project_id=project_id, user_id=user_id) async def search_all(project_id, user_id, data: schemas.SearchCardsSchema, include_series=False): @@ -497,10 +497,10 @@ async def search_all(project_id, user_id, data: schemas.SearchCardsSchema, inclu def get_all(project_id, user_id): default_search = schemas.SearchCardsSchema() - result = rows = search_all(project_id=project_id, user_id=user_id, data=default_search) + result = rows = await search_all(project_id=project_id, user_id=user_id, data=default_search) while len(rows) == default_search.limit: default_search.page += 1 - rows = search_all(project_id=project_id, user_id=user_id, data=default_search) + rows = await search_all(project_id=project_id, user_id=user_id, data=default_search) result += rows return result @@ -631,7 +631,7 @@ async def get_funnel_sessions_by_issue(user_id, project_id, metric_id, issue_id, s.filter.endTimestamp = data.endTimestamp s.filter.limit = data.limit s.filter.page = data.page - issues_list = funnels.get_issues_on_the_fly_widget(project_id=project_id, data=s.filter).get("issues", {}) + issues_list = await funnels.get_issues_on_the_fly_widget(project_id=project_id, data=s.filter).get("issues", {}) issues_list = issues_list.get("significant", []) + issues_list.get("insignificant", []) issue = None for i in issues_list: @@ -639,7 +639,7 @@ async def get_funnel_sessions_by_issue(user_id, project_id, metric_id, issue_id, issue = i break if issue is None: - issue = issues.get(project_id=project_id, issue_id=issue_id) + issue = await issues.get(project_id=project_id, issue_id=issue_id) if issue is not None: issue = {**issue, "affectedSessions": 0, @@ -648,7 +648,7 @@ async def get_funnel_sessions_by_issue(user_id, project_id, metric_id, issue_id, "lostConversions": 0, "unaffectedSessions": 0} return {"seriesId": s.series_id, "seriesName": s.name, - "sessions": sessions.search_sessions(user_id=user_id, project_id=project_id, + "sessions": await sessions.search_sessions(user_id=user_id, project_id=project_id, issue=issue, data=s.filter) if issue is not None else {"total": 0, "sessions": []}, "issue": issue} @@ -666,7 +666,7 @@ async def make_chart_from_card(project_id, user_id, metric_id, data: schemas.Car metric: schemas.CardSchema = schemas.CardSchema(**raw_metric) if metric.is_predefined: - return custom_metrics_predefined.get_metric(key=metric.metric_of, + return await custom_metrics_predefined.get_metric(key=metric.metric_of, project_id=project_id, data=data.model_dump()) elif metric.metric_type == schemas.MetricType.click_map: @@ -675,14 +675,14 @@ async def make_chart_from_card(project_id, user_id, metric_id, data: schemas.Car __get_mob_keys(project_id=project_id, session_id=raw_metric["data"]["sessionId"]) mob_exists = False for k in keys: - if StorageClient.exists(bucket=config("sessions_bucket"), key=k): + if await StorageClient.exists(bucket=config("sessions_bucket"), key=k): mob_exists = True break if mob_exists: - raw_metric["data"]['domURL'] = sessions_mobs.get_urls(session_id=raw_metric["data"]["sessionId"], + raw_metric["data"]['domURL'] = await sessions_mobs.get_urls(session_id=raw_metric["data"]["sessionId"], project_id=project_id) - raw_metric["data"]['mobsUrl'] = sessions_mobs.get_urls_depercated( + raw_metric["data"]['mobsUrl'] = await sessions_mobs.get_urls_depercated( session_id=raw_metric["data"]["sessionId"]) return raw_metric["data"] - return get_chart(project_id=project_id, data=metric, user_id=user_id) + return await get_chart(project_id=project_id, data=metric, user_id=user_id) diff --git a/api/chalicelib/core/dashboards.py b/api/chalicelib/core/dashboards.py index 88c351cda..e206812e4 100644 --- a/api/chalicelib/core/dashboards.py +++ b/api/chalicelib/core/dashboards.py @@ -224,7 +224,7 @@ async def pin_dashboard(project_id, user_id, dashboard_id): async 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) + metric_id = await custom_metrics.create_card(project_id=project_id, user_id=user_id, data=data, dashboard=True) return await add_widget(project_id=project_id, user_id=user_id, dashboard_id=dashboard_id, data=schemas.AddWidgetToDashboardPayloadSchema(metricId=metric_id)) diff --git a/api/chalicelib/core/db_request_handler.py b/api/chalicelib/core/db_request_handler.py index 73fcba802..df0a566b7 100644 --- a/api/chalicelib/core/db_request_handler.py +++ b/api/chalicelib/core/db_request_handler.py @@ -103,30 +103,30 @@ class DatabaseRequestHandler: self.logger.error(f"Database operation failed: {e}") raise - def fetchall(self): + async def fetchall(self): query = self.build_query() return await self.execute_query(query) - def fetchone(self): + async def fetchone(self): query = self.build_query() result = await self.execute_query(query) return result[0] if result else None - def insert(self, data): + async def insert(self, data): query = self.build_query(action="insert", data=data) query += " RETURNING *;" result = await self.execute_query(query, data) return result[0] if result else None - def update(self, data): + async def update(self, data): query = self.build_query(action="update", data=data) query += " RETURNING *;" result = await self.execute_query(query, data) return result[0] if result else None - def delete(self): + async def delete(self): query = self.build_query(action="delete") return await self.execute_query(query) diff --git a/api/chalicelib/core/errors.py b/api/chalicelib/core/errors.py index c83af3417..9e16791c1 100644 --- a/api/chalicelib/core/errors.py +++ b/api/chalicelib/core/errors.py @@ -608,7 +608,7 @@ async def get_trace(project_id, error_id): "preparsed": True} trace, all_exists = await sourcemaps.get_traces_group(project_id=project_id, payload=error["payload"]) if all_exists: - __save_stacktrace(error_id=error_id, data=trace) + await __save_stacktrace(error_id=error_id, data=trace) return {"sourcemapUploaded": all_exists, "trace": trace, "preparsed": False} diff --git a/api/chalicelib/core/integration_base.py b/api/chalicelib/core/integration_base.py index 2c449a9de..cb382d31c 100644 --- a/api/chalicelib/core/integration_base.py +++ b/api/chalicelib/core/integration_base.py @@ -8,9 +8,11 @@ class BaseIntegration(ABC): def __init__(self, user_id, ISSUE_CLASS): self._user_id = user_id self._issue_handler = ISSUE_CLASS(self.integration_token) - + self.integration = None + async def init(): - pass + integration = await self.get() + self.integration = integration @property @abstractmethod @@ -24,7 +26,6 @@ class BaseIntegration(ABC): @property def integration_token(self): - integration = await self.get() if integration is None: print("no token configured yet") return None diff --git a/api/chalicelib/utils/captcha.py b/api/chalicelib/utils/captcha.py index 53944d87c..c91ae16c0 100644 --- a/api/chalicelib/utils/captcha.py +++ b/api/chalicelib/utils/captcha.py @@ -11,7 +11,7 @@ def __get_captcha_config(): return config("captcha_server"), config("captcha_key") -def is_valid(response): +async def is_valid(response): if not helper.allow_captcha(): logger.info("!! Captcha is disabled") return True diff --git a/api/chalicelib/utils/pg_client.py b/api/chalicelib/utils/pg_client.py index 833936b63..1c58b28d6 100644 --- a/api/chalicelib/utils/pg_client.py +++ b/api/chalicelib/utils/pg_client.py @@ -167,13 +167,13 @@ class PostgresClient: return self.__enter__() -async def init(): +def init(): logging.info(f">PG_POOL:{config('PG_POOL', default=None)}") if config('PG_POOL', cast=bool, default=True): make_pool() -async def terminate(): +def terminate(): global postgreSQL_pool if postgreSQL_pool is not None: try: diff --git a/api/routers/core.py b/api/routers/core.py index db021da85..a304e12d3 100644 --- a/api/routers/core.py +++ b/api/routers/core.py @@ -48,13 +48,13 @@ async def events_search(projectId: int, q: str, else: return {"data": []} - result = events.search(text=q, event_type=type, project_id=projectId, source=source, key=key) + result = await events.search(text=q, event_type=type, project_id=projectId, source=source, key=key) return result @app.get('/{projectId}/integrations', tags=["integrations"]) async def get_integrations_status(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - data = integrations_global.get_global_integrations_status(tenant_id=context.tenant_id, + data = await integrations_global.get_global_integrations_status(tenant_id=context.tenant_id, user_id=context.user_id, project_id=projectId) return {"data": data} @@ -74,235 +74,235 @@ async def integration_notify(projectId: int, integration: str, webhookId: int, s "project_name": context.project.name} if integration == schemas.WebhookType.slack: if source == "sessions": - return Slack.share_session(session_id=sourceId, **args) + return await Slack.share_session(session_id=sourceId, **args) elif source == "errors": - return Slack.share_error(error_id=sourceId, **args) + return await Slack.share_error(error_id=sourceId, **args) elif integration == schemas.WebhookType.msteams: if source == "sessions": - return MSTeams.share_session(session_id=sourceId, **args) + return await MSTeams.share_session(session_id=sourceId, **args) elif source == "errors": - return MSTeams.share_error(error_id=sourceId, **args) + return await MSTeams.share_error(error_id=sourceId, **args) return {"data": None} @app.get('/integrations/sentry', tags=["integrations"]) async def get_all_sentry(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sentry.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_sentry.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/sentry', tags=["integrations"]) async def get_sentry(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sentry.get(project_id=projectId)} + return {"data": await log_tool_sentry.get(project_id=projectId)} @app.post('/{projectId}/integrations/sentry', tags=["integrations"]) async def add_edit_sentry(projectId: int, data: schemas.IntegrationSentrySchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sentry.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + return {"data": await log_tool_sentry.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/sentry', tags=["integrations"]) async def delete_sentry(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sentry.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_sentry.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.get('/{projectId}/integrations/sentry/events/{eventId}', tags=["integrations"]) async def proxy_sentry(projectId: int, eventId: str, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sentry.proxy_get(tenant_id=context.tenant_id, project_id=projectId, event_id=eventId)} + return {"data": await log_tool_sentry.proxy_get(tenant_id=context.tenant_id, project_id=projectId, event_id=eventId)} @app.get('/integrations/datadog', tags=["integrations"]) async def get_all_datadog(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_datadog.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_datadog.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/datadog', tags=["integrations"]) async def get_datadog(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_datadog.get(project_id=projectId)} + return {"data": await log_tool_datadog.get(project_id=projectId)} @app.post('/{projectId}/integrations/datadog', tags=["integrations"]) async def add_edit_datadog(projectId: int, data: schemas.IntegrationDatadogSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_datadog.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + return {"data": await log_tool_datadog.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/datadog', tags=["integrations"]) async def delete_datadog(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_datadog.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_datadog.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.get('/integrations/stackdriver', tags=["integrations"]) async def get_all_stackdriver(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_stackdriver.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_stackdriver.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/stackdriver', tags=["integrations"]) async def get_stackdriver(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_stackdriver.get(project_id=projectId)} + return {"data": await log_tool_stackdriver.get(project_id=projectId)} @app.post('/{projectId}/integrations/stackdriver', tags=["integrations"]) async def add_edit_stackdriver(projectId: int, data: schemas.IntegartionStackdriverSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_stackdriver.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + return {"data": await log_tool_stackdriver.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/stackdriver', tags=["integrations"]) async def delete_stackdriver(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_stackdriver.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_stackdriver.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.get('/integrations/newrelic', tags=["integrations"]) async def get_all_newrelic(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_newrelic.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_newrelic.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/newrelic', tags=["integrations"]) async def get_newrelic(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_newrelic.get(project_id=projectId)} + return {"data": await log_tool_newrelic.get(project_id=projectId)} @app.post('/{projectId}/integrations/newrelic', tags=["integrations"]) async def add_edit_newrelic(projectId: int, data: schemas.IntegrationNewrelicSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_newrelic.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + return {"data": await log_tool_newrelic.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/newrelic', tags=["integrations"]) async def delete_newrelic(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_newrelic.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_newrelic.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.get('/integrations/rollbar', tags=["integrations"]) async def get_all_rollbar(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_rollbar.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_rollbar.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/rollbar', tags=["integrations"]) async def get_rollbar(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_rollbar.get(project_id=projectId)} + return {"data": await log_tool_rollbar.get(project_id=projectId)} @app.post('/{projectId}/integrations/rollbar', tags=["integrations"]) async def add_edit_rollbar(projectId: int, data: schemas.IntegrationRollbarSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_rollbar.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + return {"data": await log_tool_rollbar.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/rollbar', tags=["integrations"]) async def delete_rollbar(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_rollbar.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_rollbar.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.post('/integrations/bugsnag/list_projects', tags=["integrations"]) async def list_projects_bugsnag(data: schemas.IntegrationBugsnagBasicSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_bugsnag.list_projects(auth_token=data.authorization_token)} + return {"data": await log_tool_bugsnag.list_projects(auth_token=data.authorization_token)} @app.get('/integrations/bugsnag', tags=["integrations"]) async def get_all_bugsnag(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_bugsnag.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_bugsnag.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/bugsnag', tags=["integrations"]) async def get_bugsnag(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_bugsnag.get(project_id=projectId)} + return {"data": await log_tool_bugsnag.get(project_id=projectId)} @app.post('/{projectId}/integrations/bugsnag', tags=["integrations"]) async def add_edit_bugsnag(projectId: int, data: schemas.IntegrationBugsnagSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_bugsnag.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + return {"data": await log_tool_bugsnag.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/bugsnag', tags=["integrations"]) async def delete_bugsnag(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_bugsnag.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_bugsnag.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.post('/integrations/cloudwatch/list_groups', tags=["integrations"]) async def list_groups_cloudwatch(data: schemas.IntegrationCloudwatchBasicSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_cloudwatch.list_log_groups(aws_access_key_id=data.awsAccessKeyId, + return {"data": await log_tool_cloudwatch.list_log_groups(aws_access_key_id=data.awsAccessKeyId, aws_secret_access_key=data.awsSecretAccessKey, region=data.region)} @app.get('/integrations/cloudwatch', tags=["integrations"]) async def get_all_cloudwatch(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_cloudwatch.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_cloudwatch.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/cloudwatch', tags=["integrations"]) async def get_cloudwatch(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_cloudwatch.get(project_id=projectId)} + return {"data": await log_tool_cloudwatch.get(project_id=projectId)} @app.post('/{projectId}/integrations/cloudwatch', tags=["integrations"]) async def add_edit_cloudwatch(projectId: int, data: schemas.IntegrationCloudwatchSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_cloudwatch.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + return {"data": await log_tool_cloudwatch.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/cloudwatch', tags=["integrations"]) async def delete_cloudwatch(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_cloudwatch.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_cloudwatch.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.get('/integrations/elasticsearch', tags=["integrations"]) async def get_all_elasticsearch(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_elasticsearch.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_elasticsearch.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/elasticsearch', tags=["integrations"]) async def get_elasticsearch(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_elasticsearch.get(project_id=projectId)} + return {"data": await log_tool_elasticsearch.get(project_id=projectId)} @app.post('/integrations/elasticsearch/test', tags=["integrations"]) async def test_elasticsearch_connection(data: schemas.IntegrationElasticsearchTestSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_elasticsearch.ping(tenant_id=context.tenant_id, data=data)} + return {"data": await log_tool_elasticsearch.ping(tenant_id=context.tenant_id, data=data)} @app.post('/{projectId}/integrations/elasticsearch', tags=["integrations"]) async def add_edit_elasticsearch(projectId: int, data: schemas.IntegrationElasticsearchSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): return { - "data": log_tool_elasticsearch.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + "data": await log_tool_elasticsearch.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/elasticsearch', tags=["integrations"]) async def delete_elasticsearch(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_elasticsearch.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_elasticsearch.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.get('/integrations/sumologic', tags=["integrations"]) async def get_all_sumologic(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sumologic.get_all(tenant_id=context.tenant_id)} + return {"data": await log_tool_sumologic.get_all(tenant_id=context.tenant_id)} @app.get('/{projectId}/integrations/sumologic', tags=["integrations"]) async def get_sumologic(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sumologic.get(project_id=projectId)} + return {"data": await log_tool_sumologic.get(project_id=projectId)} @app.post('/{projectId}/integrations/sumologic', tags=["integrations"]) async def add_edit_sumologic(projectId: int, data: schemas.IntegrationSumologicSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sumologic.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} + return {"data": await log_tool_sumologic.add_edit(tenant_id=context.tenant_id, project_id=projectId, data=data)} @app.delete('/{projectId}/integrations/sumologic', tags=["integrations"]) async def delete_sumologic(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": log_tool_sumologic.delete(tenant_id=context.tenant_id, project_id=projectId)} + return {"data": await log_tool_sumologic.delete(tenant_id=context.tenant_id, project_id=projectId)} @app.get('/integrations/issues', tags=["integrations"]) async def get_integration_status(context: schemas.CurrentContext = Depends(OR_context)): - error, integration = integrations_manager.get_integration(tenant_id=context.tenant_id, + error, integration = await integrations_manager.get_integration(tenant_id=context.tenant_id, user_id=context.user_id) if error is not None and integration is None: return {"data": {}} @@ -311,7 +311,7 @@ async def get_integration_status(context: schemas.CurrentContext = Depends(OR_co @app.get('/integrations/jira', tags=["integrations"]) async def get_integration_status_jira(context: schemas.CurrentContext = Depends(OR_context)): - error, integration = integrations_manager.get_integration(tenant_id=context.tenant_id, + error, integration = await integrations_manager.get_integration(tenant_id=context.tenant_id, user_id=context.user_id, tool=integration_jira_cloud.PROVIDER) if error is not None and integration is None: @@ -321,7 +321,7 @@ async def get_integration_status_jira(context: schemas.CurrentContext = Depends( @app.get('/integrations/github', tags=["integrations"]) async def get_integration_status_github(context: schemas.CurrentContext = Depends(OR_context)): - error, integration = integrations_manager.get_integration(tenant_id=context.tenant_id, + error, integration = await integrations_manager.get_integration(tenant_id=context.tenant_id, user_id=context.user_id, tool=integration_github.PROVIDER) if error is not None and integration is None: @@ -334,23 +334,23 @@ async def add_edit_jira_cloud(data: schemas.IssueTrackingJiraSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): if not str(data.url).rstrip('/').endswith('atlassian.net'): return {"errors": ["url must be a valid JIRA URL (example.atlassian.net)"]} - error, integration = integrations_manager.get_integration(tool=integration_jira_cloud.PROVIDER, + error, integration = await integrations_manager.get_integration(tool=integration_jira_cloud.PROVIDER, tenant_id=context.tenant_id, user_id=context.user_id) if error is not None and integration is None: return error - return {"data": integration.add_edit(data=data)} + return {"data": await integration.add_edit(data=data)} @app.post('/integrations/github', tags=["integrations"]) async def add_edit_github(data: schemas.IssueTrackingGithubSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - error, integration = integrations_manager.get_integration(tool=integration_github.PROVIDER, + error, integration = await integrations_manager.get_integration(tool=integration_github.PROVIDER, tenant_id=context.tenant_id, user_id=context.user_id) if error is not None: return error - return {"data": integration.add_edit(data=data)} + return {"data": await integration.add_edit(data=data)} @app.delete('/integrations/issues', tags=["integrations"]) @@ -359,29 +359,29 @@ async def delete_default_issue_tracking_tool(_=Body(None), context: schemas.Curr user_id=context.user_id) if error is not None and integration is None: return error - return {"data": integration.delete()} + return {"data": await integration.delete()} @app.delete('/integrations/jira', tags=["integrations"]) async def delete_jira_cloud(_=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - error, integration = integrations_manager.get_integration(tool=integration_jira_cloud.PROVIDER, + error, integration = await integrations_manager.get_integration(tool=integration_jira_cloud.PROVIDER, tenant_id=context.tenant_id, user_id=context.user_id, for_delete=True) if error is not None: return error - return {"data": integration.delete()} + return {"data": await integration.delete()} @app.delete('/integrations/github', tags=["integrations"]) async def delete_github(_=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - error, integration = integrations_manager.get_integration(tool=integration_github.PROVIDER, + error, integration = await integrations_manager.get_integration(tool=integration_github.PROVIDER, tenant_id=context.tenant_id, user_id=context.user_id, for_delete=True) if error is not None: return error - return {"data": integration.delete()} + return {"data": await integration.delete()} @app.get('/integrations/issues/list_projects', tags=["integrations"]) @@ -390,7 +390,7 @@ async def get_all_issue_tracking_projects(context: schemas.CurrentContext = Depe user_id=context.user_id) if error is not None: return error - data = integration.issue_handler.get_projects() + data = await integration.issue_handler.get_projects() if "errors" in data: return data return {"data": data} @@ -398,11 +398,11 @@ async def get_all_issue_tracking_projects(context: schemas.CurrentContext = Depe @app.get('/integrations/issues/{integrationProjectId}', tags=["integrations"]) async def get_integration_metadata(integrationProjectId: int, context: schemas.CurrentContext = Depends(OR_context)): - error, integration = integrations_manager.get_integration(tenant_id=context.tenant_id, + error, integration = await integrations_manager.get_integration(tenant_id=context.tenant_id, user_id=context.user_id) if error is not None: return error - data = integration.issue_handler.get_metas(integrationProjectId) + data = await integration.issue_handler.get_metas(integrationProjectId) if "errors" in data.keys(): return data return {"data": data} @@ -410,7 +410,7 @@ async def get_integration_metadata(integrationProjectId: int, context: schemas.C @app.get('/{projectId}/assignments', tags=["assignment"]) async def get_all_assignments(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_assignments.get_all(project_id=projectId, user_id=context.user_id) + data = await sessions_assignments.get_all(project_id=projectId, user_id=context.user_id) return { 'data': data } @@ -420,7 +420,7 @@ async def get_all_assignments(projectId: int, context: schemas.CurrentContext = async def create_issue_assignment(projectId: int, sessionId: int, integrationProjectId, data: schemas.AssignmentSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_assignments.create_new_assignment(tenant_id=context.tenant_id, project_id=projectId, + data = await sessions_assignments.create_new_assignment(tenant_id=context.tenant_id, project_id=projectId, session_id=sessionId, creator_id=context.user_id, assignee=data.assignee, description=data.description, title=data.title, @@ -435,13 +435,13 @@ async def create_issue_assignment(projectId: int, sessionId: int, integrationPro @app.get('/{projectId}/gdpr', tags=["projects", "gdpr"]) async def get_gdpr(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": projects.get_gdpr(project_id=projectId)} + return {"data": await projects.get_gdpr(project_id=projectId)} @app.post('/{projectId}/gdpr', tags=["projects", "gdpr"]) async def edit_gdpr(projectId: int, data: schemas.GdprSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - result = projects.edit_gdpr(project_id=projectId, gdpr=data) + result = await projects.edit_gdpr(project_id=projectId, gdpr=data) if "errors" in result: return result return {"data": result} @@ -451,12 +451,12 @@ async def edit_gdpr(projectId: int, data: schemas.GdprSchema = Body(...), async def reset_password_handler(data: schemas.ForgetPasswordPayloadSchema = Body(...)): if len(data.email) < 5: return {"errors": ["please provide a valid email address"]} - return reset_password.reset(data=data) + return await reset_password.reset(data=data) @app.get('/{projectId}/metadata', tags=["metadata"]) async def get_metadata(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": metadata.get(project_id=projectId)} + return {"data": await metadata.get(project_id=projectId)} # @app.post('/{projectId}/metadata/list', tags=["metadata"]) @@ -468,20 +468,20 @@ async def get_metadata(projectId: int, context: schemas.CurrentContext = Depends @app.post('/{projectId}/metadata', tags=["metadata"]) async def add_metadata(projectId: int, data: schemas.MetadataSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return metadata.add(tenant_id=context.tenant_id, project_id=projectId, new_name=data.key) + return await metadata.add(tenant_id=context.tenant_id, project_id=projectId, new_name=data.key) @app.post('/{projectId}/metadata/{index}', tags=["metadata"]) async def edit_metadata(projectId: int, index: int, data: schemas.MetadataSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return metadata.edit(tenant_id=context.tenant_id, project_id=projectId, index=index, + return await metadata.edit(tenant_id=context.tenant_id, project_id=projectId, index=index, new_name=data.key) @app.delete('/{projectId}/metadata/{index}', tags=["metadata"]) async def delete_metadata(projectId: int, index: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return metadata.delete(tenant_id=context.tenant_id, project_id=projectId, index=index) + return await metadata.delete(tenant_id=context.tenant_id, project_id=projectId, index=index) @app.get('/{projectId}/metadata/search', tags=["metadata"]) @@ -492,44 +492,44 @@ async def search_metadata(projectId: int, q: str, key: str, context: schemas.Cur return {"errors": ["please provide a value for search"]} if len(key) == 0: return {"errors": ["please provide a key for search"]} - return metadata.search(tenant_id=context.tenant_id, project_id=projectId, value=q, key=key) + return await metadata.search(tenant_id=context.tenant_id, project_id=projectId, value=q, key=key) @app.get('/{projectId}/integration/sources', tags=["integrations"]) async def search_integrations(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return log_tools.search(project_id=projectId) + return await log_tools.search(project_id=projectId) @app.get('/{projectId}/sample_rate', tags=["projects"]) async def get_capture_status(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": projects.get_capture_status(project_id=projectId)} + return {"data": await projects.get_capture_status(project_id=projectId)} @app.post('/{projectId}/sample_rate', tags=["projects"]) async def update_capture_status(projectId: int, data: schemas.SampleRateSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": projects.update_capture_status(project_id=projectId, changes=data)} + return {"data": await projects.update_capture_status(project_id=projectId, changes=data)} @app.post('/{projectId}/conditions', tags=["projects"]) async def update_conditions(projectId: int, data: schemas.ProjectSettings = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": projects.update_conditions(project_id=projectId, changes=data)} + return {"data": await projects.update_conditions(project_id=projectId, changes=data)} @app.get('/{projectId}/conditions', tags=["projects"]) async def get_conditions(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": projects.get_conditions(project_id=projectId)} + return {"data": await projects.get_conditions(project_id=projectId)} @app.get('/announcements', tags=["announcements"]) async def get_all_announcements(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": announcements.get_all(user_id=context.user_id)} + return {"data": await announcements.get_all(user_id=context.user_id)} @app.get('/announcements/view', tags=["announcements"]) async def get_all_announcements(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": announcements.view(user_id=context.user_id)} + return {"data": await announcements.view(user_id=context.user_id)} @app.get('/show_banner', tags=["banner"]) @@ -540,93 +540,93 @@ async def errors_merge(context: schemas.CurrentContext = Depends(OR_context)): @app.post('/{projectId}/alerts', tags=["alerts"]) async def create_alert(projectId: int, data: schemas.AlertSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return alerts.create(project_id=projectId, data=data) + return await alerts.create(project_id=projectId, data=data) @app.get('/{projectId}/alerts', tags=["alerts"]) async def get_all_alerts(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": alerts.get_all(project_id=projectId)} + return {"data": await alerts.get_all(project_id=projectId)} @app.get('/{projectId}/alerts/triggers', tags=["alerts", "customMetrics"]) async def get_alerts_triggers(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": alerts.get_predefined_values() \ - + custom_metrics.get_series_for_alert(project_id=projectId, user_id=context.user_id)} + return {"data": await alerts.get_predefined_values() \ + + await custom_metrics.get_series_for_alert(project_id=projectId, user_id=context.user_id)} @app.get('/{projectId}/alerts/{alertId}', tags=["alerts"]) async def get_alert(projectId: int, alertId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": alerts.get(id=alertId)} + return {"data": await alerts.get(id=alertId)} @app.post('/{projectId}/alerts/{alertId}', tags=["alerts"]) async def update_alert(projectId: int, alertId: int, data: schemas.AlertSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return alerts.update(id=alertId, data=data) + return await alerts.update(id=alertId, data=data) @app.delete('/{projectId}/alerts/{alertId}', tags=["alerts"]) async def delete_alert(projectId: int, alertId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return alerts.delete(project_id=projectId, alert_id=alertId) + return await alerts.delete(project_id=projectId, alert_id=alertId) @app_apikey.put('/{projectKey}/sourcemaps/', tags=["sourcemaps"]) @app_apikey.put('/{projectKey}/sourcemaps', tags=["sourcemaps"]) async def sign_sourcemap_for_upload(projectKey: str, data: schemas.SourcemapUploadPayloadSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": sourcemaps.presign_upload_urls(project_id=context.project.project_id, urls=data.urls)} + return {"data": await sourcemaps.presign_upload_urls(project_id=context.project.project_id, urls=data.urls)} @app.get('/config/weekly_report', tags=["weekly report config"]) async def get_weekly_report_config(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": weekly_report.get_config(user_id=context.user_id)} + return {"data": await weekly_report.get_config(user_id=context.user_id)} @app.post('/config/weekly_report', tags=["weekly report config"]) async def edit_weekly_report_config(data: schemas.WeeklyReportConfigSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": weekly_report.edit_config(user_id=context.user_id, weekly_report=data.weekly_report)} + return {"data": await weekly_report.edit_config(user_id=context.user_id, weekly_report=data.weekly_report)} @app.get('/{projectId}/issue_types', tags=["issues"]) async def issue_types(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": issues.get_all_types()} + return {"data": await issues.get_all_types()} @app.get('/issue_types', tags=["issues"]) async def all_issue_types(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": issues.get_all_types()} + return {"data": await issues.get_all_types()} @app.get('/{projectId}/assist/sessions', tags=["assist"]) async def get_sessions_live(projectId: int, userId: str = None, context: schemas.CurrentContext = Depends(OR_context)): - data = assist.get_live_sessions_ws_user_id(projectId, user_id=userId) + data = await assist.get_live_sessions_ws_user_id(projectId, user_id=userId) return {'data': data} @app.post('/{projectId}/assist/sessions', tags=["assist"]) async def sessions_live(projectId: int, data: schemas.LiveSessionsSearchPayloadSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - data = assist.get_live_sessions_ws(projectId, body=data) + data = await assist.get_live_sessions_ws(projectId, body=data) return {'data': data} @app.post('/{projectId}/mobile/{sessionId}/urls', tags=['mobile']) async def mobile_signe(projectId: int, sessionId: int, data: schemas.MobileSignPayloadSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": mobile.sign_keys(project_id=projectId, session_id=sessionId, keys=data.keys)} + return {"data": await mobile.sign_keys(project_id=projectId, session_id=sessionId, keys=data.keys)} @app.post('/projects', tags=['projects'], dependencies=[OR_role("owner", "admin")]) async def create_project(data: schemas.CreateProjectSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return projects.create(tenant_id=context.tenant_id, user_id=context.user_id, data=data) + return await projects.create(tenant_id=context.tenant_id, user_id=context.user_id, data=data) @app.get('/projects/{projectId}', tags=['projects']) async def get_project(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - data = projects.get_project(tenant_id=context.tenant_id, project_id=projectId, include_last_session=True, + data = await projects.get_project(tenant_id=context.tenant_id, project_id=projectId, include_last_session=True, include_gdpr=True) if data is None: return {"errors": ["project not found"]} @@ -636,46 +636,46 @@ async def get_project(projectId: int, context: schemas.CurrentContext = Depends( @app.put('/projects/{projectId}', tags=['projects'], dependencies=[OR_role("owner", "admin")]) async def edit_project(projectId: int, data: schemas.CreateProjectSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return projects.edit(tenant_id=context.tenant_id, user_id=context.user_id, data=data, project_id=projectId) + return await projects.edit(tenant_id=context.tenant_id, user_id=context.user_id, data=data, project_id=projectId) @app.delete('/projects/{projectId}', tags=['projects'], dependencies=[OR_role("owner", "admin")]) async def delete_project(projectId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return projects.delete(tenant_id=context.tenant_id, user_id=context.user_id, project_id=projectId) + return await projects.delete(tenant_id=context.tenant_id, user_id=context.user_id, project_id=projectId) @app.get('/client/new_api_key', tags=['client']) async def generate_new_tenant_token(context: schemas.CurrentContext = Depends(OR_context)): return { - 'data': tenants.generate_new_api_key(context.tenant_id) + 'data': await tenants.generate_new_api_key(context.tenant_id) } @app.post('/users/modules', tags=['users']) async def update_user_module(context: schemas.CurrentContext = Depends(OR_context), data: schemas.ModuleStatus = Body(...)): - return {"data": users.update_user_module(context.user_id, data)} + return {"data": await users.update_user_module(context.user_id, data)} @app.get('/notifications', tags=['notifications']) async def get_notifications(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": notifications.get_all(tenant_id=context.tenant_id, user_id=context.user_id)} + return {"data": await notifications.get_all(tenant_id=context.tenant_id, user_id=context.user_id)} @app.get('/notifications/count', tags=['notifications']) async def get_notifications_count(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": notifications.get_all_count(tenant_id=context.tenant_id, user_id=context.user_id)} + return {"data": await notifications.get_all_count(tenant_id=context.tenant_id, user_id=context.user_id)} @app.get('/notifications/{notificationId}/view', tags=['notifications']) async def view_notifications(notificationId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": notifications.view_notification(notification_ids=[notificationId], user_id=context.user_id)} + return {"data": await notifications.view_notification(notification_ids=[notificationId], user_id=context.user_id)} @app.post('/notifications/view', tags=['notifications']) async def batch_view_notifications(data: schemas.NotificationsViewSchema, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": notifications.view_notification(notification_ids=data.ids, + return {"data": await notifications.view_notification(notification_ids=data.ids, startTimestamp=data.startTimestamp, endTimestamp=data.endTimestamp, user_id=context.user_id, @@ -686,84 +686,84 @@ async def batch_view_notifications(data: schemas.NotificationsViewSchema, async def get_boarding_state(context: schemas.CurrentContext = Depends(OR_context)): if config("LOCAL_DEV", cast=bool, default=False): return {"data": ""} - return {"data": boarding.get_state(tenant_id=context.tenant_id)} + return {"data": await boarding.get_state(tenant_id=context.tenant_id)} @app.get('/boarding/installing', tags=['boarding']) async def get_boarding_state_installing(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": boarding.get_state_installing(tenant_id=context.tenant_id)} + return {"data": await boarding.get_state_installing(tenant_id=context.tenant_id)} @app.get('/boarding/identify-users', tags=["boarding"]) async def get_boarding_state_identify_users(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": boarding.get_state_identify_users(tenant_id=context.tenant_id)} + return {"data": await boarding.get_state_identify_users(tenant_id=context.tenant_id)} @app.get('/boarding/manage-users', tags=["boarding"]) async def get_boarding_state_manage_users(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": boarding.get_state_manage_users(tenant_id=context.tenant_id)} + return {"data": await boarding.get_state_manage_users(tenant_id=context.tenant_id)} @app.get('/boarding/integrations', tags=["boarding"]) async def get_boarding_state_integrations(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": boarding.get_state_integrations(tenant_id=context.tenant_id)} + return {"data": await boarding.get_state_integrations(tenant_id=context.tenant_id)} @app.get('/integrations/slack/channels', tags=["integrations"]) async def get_slack_channels(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": webhook.get_by_type(tenant_id=context.tenant_id, webhook_type=schemas.WebhookType.slack)} + return {"data": await webhook.get_by_type(tenant_id=context.tenant_id, webhook_type=schemas.WebhookType.slack)} @app.get('/integrations/slack/{integrationId}', tags=["integrations"]) async def get_slack_webhook(integrationId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": Slack.get_integration(tenant_id=context.tenant_id, integration_id=integrationId)} + return {"data": await Slack.get_integration(tenant_id=context.tenant_id, integration_id=integrationId)} @app.delete('/integrations/slack/{integrationId}', tags=["integrations"]) async def delete_slack_integration(integrationId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return webhook.delete(tenant_id=context.tenant_id, webhook_id=integrationId) + return await webhook.delete(tenant_id=context.tenant_id, webhook_id=integrationId) @app.put('/webhooks', tags=["webhooks"]) async def add_edit_webhook(data: schemas.WebhookSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": webhook.add_edit(tenant_id=context.tenant_id, data=data, replace_none=True)} + return {"data": await webhook.add_edit(tenant_id=context.tenant_id, data=data, replace_none=True)} @app.get('/webhooks', tags=["webhooks"]) async def get_webhooks(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": webhook.get_by_tenant(tenant_id=context.tenant_id, replace_none=True)} + return {"data": await webhook.get_by_tenant(tenant_id=context.tenant_id, replace_none=True)} @app.delete('/webhooks/{webhookId}', tags=["webhooks"]) async def delete_webhook(webhookId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return webhook.delete(tenant_id=context.tenant_id, webhook_id=webhookId) + return await webhook.delete(tenant_id=context.tenant_id, webhook_id=webhookId) @app.get('/client/members', tags=["client"], dependencies=[OR_role("owner", "admin")]) async def get_members(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": users.get_members(tenant_id=context.tenant_id)} + return {"data": await users.get_members(tenant_id=context.tenant_id)} @app.get('/client/members/{memberId}/reset', tags=["client"], dependencies=[OR_role("owner", "admin")]) async def reset_reinvite_member(memberId: int, context: schemas.CurrentContext = Depends(OR_context)): - return users.reset_member(tenant_id=context.tenant_id, editor_id=context.user_id, user_id_to_update=memberId) + return await users.reset_member(tenant_id=context.tenant_id, editor_id=context.user_id, user_id_to_update=memberId) @app.delete('/client/members/{memberId}', tags=["client"], dependencies=[OR_role("owner", "admin")]) async def delete_member(memberId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return users.delete_member(tenant_id=context.tenant_id, user_id=context.user_id, id_to_delete=memberId) + return await users.delete_member(tenant_id=context.tenant_id, user_id=context.user_id, id_to_delete=memberId) @app.get('/account/new_api_key', tags=["account"], dependencies=[OR_role("owner", "admin")]) async def generate_new_user_token(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": users.generate_new_api_key(user_id=context.user_id)} + return {"data": await users.generate_new_api_key(user_id=context.user_id)} @app.post('/account/password', tags=["account"]) async def change_client_password(data: schemas.EditUserPasswordSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return users.change_password(email=context.email, old_password=data.old_password.get_secret_value(), + return await users.change_password(email=context.email, old_password=data.old_password.get_secret_value(), new_password=data.new_password.get_secret_value(), tenant_id=context.tenant_id, user_id=context.user_id) @@ -771,29 +771,29 @@ async def change_client_password(data: schemas.EditUserPasswordSchema = Body(... @app.post('/{projectId}/saved_search', tags=["savedSearch"]) async def add_saved_search(projectId: int, data: schemas.SavedSearchSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return saved_search.create(project_id=projectId, user_id=context.user_id, data=data) + return await saved_search.create(project_id=projectId, user_id=context.user_id, data=data) @app.get('/{projectId}/saved_search', tags=["savedSearch"]) async def get_saved_searches(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": saved_search.get_all(project_id=projectId, user_id=context.user_id, details=True)} + return {"data": await saved_search.get_all(project_id=projectId, user_id=context.user_id, details=True)} @app.get('/{projectId}/saved_search/{search_id}', tags=["savedSearch"]) async def get_saved_search(projectId: int, search_id: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": saved_search.get(project_id=projectId, search_id=search_id, user_id=context.user_id)} + return {"data": await saved_search.get(project_id=projectId, search_id=search_id, user_id=context.user_id)} @app.post('/{projectId}/saved_search/{search_id}', tags=["savedSearch"]) async def update_saved_search(projectId: int, search_id: int, data: schemas.SavedSearchSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": saved_search.update(user_id=context.user_id, search_id=search_id, data=data, project_id=projectId)} + return {"data": await saved_search.update(user_id=context.user_id, search_id=search_id, data=data, project_id=projectId)} @app.delete('/{projectId}/saved_search/{search_id}', tags=["savedSearch"]) async def delete_saved_search(projectId: int, search_id: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": saved_search.delete(project_id=projectId, user_id=context.user_id, search_id=search_id)} + return {"data": await saved_search.delete(project_id=projectId, user_id=context.user_id, search_id=search_id)} @app.get('/limits', tags=['accounts']) @@ -808,13 +808,13 @@ async def get_limits(context: schemas.CurrentContext = Depends(OR_context)): @app.get('/integrations/msteams/channels', tags=["integrations"]) async def get_msteams_channels(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": webhook.get_by_type(tenant_id=context.tenant_id, webhook_type=schemas.WebhookType.msteams)} + return {"data": await webhook.get_by_type(tenant_id=context.tenant_id, webhook_type=schemas.WebhookType.msteams)} @app.post('/integrations/msteams', tags=['integrations']) async def add_msteams_integration(data: schemas.AddCollaborationSchema, context: schemas.CurrentContext = Depends(OR_context)): - n = MSTeams.add(tenant_id=context.tenant_id, data=data) + n = await MSTeams.add(tenant_id=context.tenant_id, data=data) if n is None: return { "errors": [ @@ -827,23 +827,23 @@ async def add_msteams_integration(data: schemas.AddCollaborationSchema, async def edit_msteams_integration(webhookId: int, data: schemas.EditCollaborationSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): if len(data.url.unicode_string()) > 0: - old = MSTeams.get_integration(tenant_id=context.tenant_id, integration_id=webhookId) + old = await MSTeams.get_integration(tenant_id=context.tenant_id, integration_id=webhookId) if not old: return {"errors": ["MsTeams integration not found."]} if old["endpoint"] != data.url.unicode_string(): - if not MSTeams.say_hello(data.url.unicode_string()): + if not await MSTeams.say_hello(data.url.unicode_string()): return { "errors": [ "We couldn't send you a test message on your Microsoft Teams channel. Please verify your webhook url."] } - return {"data": webhook.update(tenant_id=context.tenant_id, webhook_id=webhookId, + return {"data": await webhook.update(tenant_id=context.tenant_id, webhook_id=webhookId, changes={"name": data.name, "endpoint": data.url.unicode_string()})} @app.delete('/integrations/msteams/{webhookId}', tags=["integrations"]) async def delete_msteams_integration(webhookId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - return webhook.delete(tenant_id=context.tenant_id, webhook_id=webhookId) + return await webhook.delete(tenant_id=context.tenant_id, webhook_id=webhookId) @app.get('/{project_id}/check-recording-status', tags=["sessions"]) @@ -865,7 +865,7 @@ async def check_recording_status(project_id: int): "sessions_count": int # The total count of sessions } """ - return {"data": sessions.check_recording_status(project_id=project_id)} + return {"data": await sessions.check_recording_status(project_id=project_id)} @public_app.get('/', tags=["health"]) @@ -876,23 +876,23 @@ async def health_check(): @app.post('/{projectId}/tags', tags=["tags"]) async def tags_create(projectId: int, data: schemas.TagCreate = Body(), context: schemas.CurrentContext = Depends(OR_context)): - data = tags.create_tag(project_id=projectId, data=data) + data = await tags.create_tag(project_id=projectId, data=data) return {'data': data} @app.put('/{projectId}/tags/{tagId}', tags=["tags"]) async def tags_update(projectId: int, tagId: int, data: schemas.TagUpdate = Body(), context: schemas.CurrentContext = Depends(OR_context)): - data = tags.update_tag(project_id=projectId, tag_id=tagId, data=data) + data = await tags.update_tag(project_id=projectId, tag_id=tagId, data=data) return {'data': data} @app.get('/{projectId}/tags', tags=["tags"]) async def tags_list(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - data = tags.list_tags(project_id=projectId) + data = await tags.list_tags(project_id=projectId) return {'data': data} @app.delete('/{projectId}/tags/{tagId}', tags=["tags"]) async def tags_delete(projectId: int, tagId: int, context: schemas.CurrentContext = Depends(OR_context)): - data = tags.delete_tag(projectId, tag_id=tagId) + data = await tags.delete_tag(projectId, tag_id=tagId) return {'data': data} diff --git a/api/routers/core_dynamic.py b/api/routers/core_dynamic.py index 3688d65c1..2d1f279b6 100644 --- a/api/routers/core_dynamic.py +++ b/api/routers/core_dynamic.py @@ -48,13 +48,13 @@ if not tenants.tenants_exists_sync(use_pool=False): @public_app.post('/login', tags=["authentication"]) async def login_user(response: JSONResponse, data: schemas.UserLoginSchema = Body(...)): - if helper.allow_captcha() and not captcha.is_valid(data.g_recaptcha_response): + if helper.allow_captcha() and not await captcha.is_valid(data.g_recaptcha_response): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid captcha." ) - r = users.authenticate(data.email, data.password.get_secret_value()) + r = await users.authenticate(data.email, data.password.get_secret_value()) if r is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, @@ -83,14 +83,14 @@ async def login_user(response: JSONResponse, data: schemas.UserLoginSchema = Bod @app.get('/logout', tags=["login"]) async def logout_user(response: Response, context: schemas.CurrentContext = Depends(OR_context)): - users.logout(user_id=context.user_id) + await users.logout(user_id=context.user_id) response.delete_cookie(key="refreshToken", path="/api/refresh") return {"data": "success"} @app.get('/refresh', tags=["login"]) async def refresh_login(context: schemas.CurrentContext = Depends(OR_context)): - r = users.refresh(user_id=context.user_id) + r = await users.refresh(user_id=context.user_id) content = {"jwt": r.get("jwt")} response = JSONResponse(content=content) response.set_cookie(key="refreshToken", value=r.get("refreshToken"), path="/api/refresh", @@ -100,8 +100,8 @@ async def refresh_login(context: schemas.CurrentContext = Depends(OR_context)): @app.get('/account', tags=['accounts']) async def get_account(context: schemas.CurrentContext = Depends(OR_context)): - r = users.get(tenant_id=context.tenant_id, user_id=context.user_id) - t = tenants.get_by_tenant_id(context.tenant_id) + r = await users.get(tenant_id=context.tenant_id, user_id=context.user_id) + t = await tenants.get_by_tenant_id(context.tenant_id) if t is not None: t["createdAt"] = TimeUTC.datetime_to_timestamp(t["createdAt"]) t["tenantName"] = t.pop("name") @@ -118,14 +118,14 @@ async def get_account(context: schemas.CurrentContext = Depends(OR_context)): @app.post('/account', tags=["account"]) async def edit_account(data: schemas.EditAccountSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return users.edit_account(tenant_id=context.tenant_id, user_id=context.user_id, changes=data) + return await users.edit_account(tenant_id=context.tenant_id, user_id=context.user_id, changes=data) @app.post('/integrations/slack', tags=['integrations']) @app.put('/integrations/slack', tags=['integrations']) async def add_slack_integration(data: schemas.AddCollaborationSchema, context: schemas.CurrentContext = Depends(OR_context)): - n = Slack.add(tenant_id=context.tenant_id, data=data) + n = await Slack.add(tenant_id=context.tenant_id, data=data) if n is None: return { "errors": ["We couldn't send you a test message on your Slack channel. Please verify your webhook url."] @@ -137,11 +137,11 @@ async def add_slack_integration(data: schemas.AddCollaborationSchema, async def edit_slack_integration(integrationId: int, data: schemas.EditCollaborationSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): if len(data.url) > 0: - old = Slack.get_integration(tenant_id=context.tenant_id, integration_id=integrationId) + old = await Slack.get_integration(tenant_id=context.tenant_id, integration_id=integrationId) if not old: return {"errors": ["Slack integration not found."]} if old["endpoint"] != data.url: - if not Slack.say_hello(data.url): + if not await Slack.say_hello(data.url): return { "errors": [ "We couldn't send you a test message on your Slack channel. Please verify your webhook url."] @@ -153,7 +153,7 @@ async def edit_slack_integration(integrationId: int, data: schemas.EditCollabora @app.post('/client/members', tags=["client"], dependencies=[OR_role("owner", "admin")]) async def add_member(background_tasks: BackgroundTasks, data: schemas.CreateMemberSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return users.create_member(tenant_id=context.tenant_id, user_id=context.user_id, data=data, + return await users.create_member(tenant_id=context.tenant_id, user_id=context.user_id, data=data, background_tasks=background_tasks) @@ -161,7 +161,7 @@ async def add_member(background_tasks: BackgroundTasks, data: schemas.CreateMemb async def process_invitation_link(token: str): if token is None or len(token) < 64: return {"errors": ["please provide a valid invitation"]} - user = users.get_by_invitation_token(token) + user = await users.get_by_invitation_token(token) if user is None: return {"errors": ["invitation not found"]} if user["expiredInvitation"]: @@ -170,7 +170,7 @@ async def process_invitation_link(token: str): and user["changePwdToken"] is not None and user["changePwdAge"] < -5 * 60: pass_token = user["changePwdToken"] else: - pass_token = users.allow_password_change(user_id=user["userId"]) + pass_token = await users.allow_password_change(user_id=user["userId"]) return RedirectResponse(url=config("SITE_URL") + config("change_password_link") % (token, pass_token)) @@ -178,19 +178,19 @@ async def process_invitation_link(token: str): async def change_password_by_invitation(data: schemas.EditPasswordByInvitationSchema = Body(...)): if data is None or len(data.invitation) < 64 or len(data.passphrase) < 8: return {"errors": ["please provide a valid invitation & pass"]} - user = users.get_by_invitation_token(token=data.invitation, pass_token=data.passphrase) + user = await users.get_by_invitation_token(token=data.invitation, pass_token=data.passphrase) if user is None: return {"errors": ["invitation not found"]} if user["expiredChange"]: return {"errors": ["expired change, please re-use the invitation link"]} - return users.set_password_invitation(new_password=data.password.get_secret_value(), user_id=user["userId"]) + return await users.set_password_invitation(new_password=data.password.get_secret_value(), user_id=user["userId"]) @app.put('/client/members/{memberId}', tags=["client"], dependencies=[OR_role("owner", "admin")]) async def edit_member(memberId: int, data: schemas.EditMemberSchema, context: schemas.CurrentContext = Depends(OR_context)): - return users.edit_member(tenant_id=context.tenant_id, editor_id=context.user_id, changes=data, + return await users.edit_member(tenant_id=context.tenant_id, editor_id=context.user_id, changes=data, user_id_to_update=memberId) @@ -204,13 +204,13 @@ async def search_sessions_by_metadata(key: str, value: str, projectId: Optional[ if len(key) == 0: return {"errors": ["please provide a key for search"]} return { - "data": sessions.search_by_metadata(tenant_id=context.tenant_id, user_id=context.user_id, m_value=value, + "data": await sessions.search_by_metadata(tenant_id=context.tenant_id, user_id=context.user_id, m_value=value, m_key=key, project_id=projectId)} @app.get('/projects', tags=['projects']) async def get_projects(context: schemas.CurrentContext = Depends(OR_context)): - return {"data": projects.get_projects(tenant_id=context.tenant_id, gdpr=True, recorded=True)} + return {"data": await projects.get_projects(tenant_id=context.tenant_id, gdpr=True, recorded=True)} # for backward compatibility @@ -221,7 +221,7 @@ async def get_session(projectId: int, sessionId: Union[int, str], background_tas return {"errors": ["session not found"]} else: sessionId = int(sessionId) - data = sessions_replay.get_by_id2_pg(project_id=projectId, session_id=sessionId, full_data=True, + data = await sessions_replay.get_by_id2_pg(project_id=projectId, session_id=sessionId, full_data=True, include_fav_viewed=True, group_metadata=True, context=context) if data is None: return {"errors": ["session not found"]} @@ -236,7 +236,7 @@ async def get_session(projectId: int, sessionId: Union[int, str], background_tas @app.post('/{projectId}/sessions/search', tags=["sessions"]) async def sessions_search(projectId: int, data: schemas.SessionsSearchPayloadSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions.search_sessions(data=data, project_id=projectId, user_id=context.user_id, + data = await sessions.search_sessions(data=data, project_id=projectId, user_id=context.user_id, platform=context.project.platform) return {'data': data} @@ -244,7 +244,7 @@ async def sessions_search(projectId: int, data: schemas.SessionsSearchPayloadSch @app.post('/{projectId}/sessions/search/ids', tags=["sessions"]) async def session_ids_search(projectId: int, data: schemas.SessionsSearchPayloadSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions.search_sessions(data=data, project_id=projectId, user_id=context.user_id, ids_only=True, + data = await sessions.search_sessions(data=data, project_id=projectId, user_id=context.user_id, ids_only=True, platform=context.project.platform) return {'data': data} @@ -256,7 +256,7 @@ async def get_session_events(projectId: int, sessionId: Union[int, str], backgro return {"errors": ["session not found"]} else: sessionId = int(sessionId) - data = sessions_replay.get_replay(project_id=projectId, session_id=sessionId, full_data=True, + data = await sessions_replay.get_replay(project_id=projectId, session_id=sessionId, full_data=True, include_fav_viewed=True, group_metadata=True, context=context) if data is None: return {"errors": ["session not found"]} @@ -275,7 +275,7 @@ async def get_session_events(projectId: int, sessionId: Union[int, str], return {"errors": ["session not found"]} else: sessionId = int(sessionId) - data = sessions_replay.get_events(project_id=projectId, session_id=sessionId) + data = await sessions_replay.get_events(project_id=projectId, session_id=sessionId) if data is None: return {"errors": ["session not found"]} @@ -287,7 +287,7 @@ async def get_session_events(projectId: int, sessionId: Union[int, str], @app.get('/{projectId}/sessions/{sessionId}/errors/{errorId}/sourcemaps', tags=["sessions", "sourcemaps"]) async def get_error_trace(projectId: int, sessionId: int, errorId: str, context: schemas.CurrentContext = Depends(OR_context)): - data = errors.get_trace(project_id=projectId, error_id=errorId) + data = await errors.get_trace(project_id=projectId, error_id=errorId) if "errors" in data: return data return { @@ -298,7 +298,7 @@ async def get_error_trace(projectId: int, sessionId: int, errorId: str, @app.get('/{projectId}/errors/{errorId}', tags=['errors']) async def errors_get_details(projectId: int, errorId: str, background_tasks: BackgroundTasks, density24: int = 24, density30: int = 30, context: schemas.CurrentContext = Depends(OR_context)): - data = errors.get_details(project_id=projectId, user_id=context.user_id, error_id=errorId, + data = await errors.get_details(project_id=projectId, user_id=context.user_id, error_id=errorId, **{"density24": density24, "density30": density30}) if data.get("data") is not None: background_tasks.add_task(errors_viewed.viewed_error, project_id=projectId, user_id=context.user_id, @@ -309,7 +309,7 @@ async def errors_get_details(projectId: int, errorId: str, background_tasks: Bac @app.get('/{projectId}/errors/{errorId}/sourcemaps', tags=['errors']) async def errors_get_details_sourcemaps(projectId: int, errorId: str, context: schemas.CurrentContext = Depends(OR_context)): - data = errors.get_trace(project_id=projectId, error_id=errorId) + data = await errors.get_trace(project_id=projectId, error_id=errorId) if "errors" in data: return data return { @@ -322,15 +322,15 @@ async def add_remove_favorite_error(projectId: int, errorId: str, action: str, s endDate: int = TimeUTC.now(), context: schemas.CurrentContext = Depends(OR_context)): if action == "favorite": - return errors_favorite.favorite_error(project_id=projectId, user_id=context.user_id, error_id=errorId) + return await errors_favorite.favorite_error(project_id=projectId, user_id=context.user_id, error_id=errorId) elif action == "sessions": start_date = startDate end_date = endDate return { - "data": errors.get_sessions(project_id=projectId, user_id=context.user_id, error_id=errorId, + "data": await errors.get_sessions(project_id=projectId, user_id=context.user_id, error_id=errorId, start_date=start_date, end_date=end_date)} elif action in list(errors.ACTION_STATE.keys()): - return errors.change_state(project_id=projectId, user_id=context.user_id, error_id=errorId, action=action) + return await errors.change_state(project_id=projectId, user_id=context.user_id, error_id=errorId, action=action) else: return {"errors": ["undefined action"]} @@ -338,9 +338,9 @@ async def add_remove_favorite_error(projectId: int, errorId: str, action: str, s @app.get('/{projectId}/assist/sessions/{sessionId}', tags=["assist"]) async def get_live_session(projectId: int, sessionId: str, background_tasks: BackgroundTasks, context: schemas.CurrentContext = Depends(OR_context)): - data = assist.get_live_session_by_id(project_id=projectId, session_id=sessionId) + data = await assist.get_live_session_by_id(project_id=projectId, session_id=sessionId) if data is None: - data = sessions_replay.get_replay(context=context, project_id=projectId, session_id=sessionId, + data = await sessions_replay.get_replay(context=context, project_id=projectId, session_id=sessionId, full_data=True, include_fav_viewed=True, group_metadata=True, live=False) if data is None: return {"errors": ["session not found"]} @@ -358,13 +358,13 @@ async def get_live_session_replay_file(projectId: int, sessionId: Union[int, str return not_found else: sessionId = int(sessionId) - if not sessions.session_exists(project_id=projectId, session_id=sessionId): + if not await sessions.session_exists(project_id=projectId, session_id=sessionId): print(f"{projectId}/{sessionId} not found in DB.") - if not assist.session_exists(project_id=projectId, session_id=sessionId): + if not await assist.session_exists(project_id=projectId, session_id=sessionId): print(f"{projectId}/{sessionId} not found in Assist.") return not_found - path = assist.get_raw_mob_by_id(project_id=projectId, session_id=sessionId) + path = await assist.get_raw_mob_by_id(project_id=projectId, session_id=sessionId) if path is None: return not_found @@ -379,13 +379,13 @@ async def get_live_session_devtools_file(projectId: int, sessionId: Union[int, s return not_found else: sessionId = int(sessionId) - if not sessions.session_exists(project_id=projectId, session_id=sessionId): + if not await sessions.session_exists(project_id=projectId, session_id=sessionId): print(f"{projectId}/{sessionId} not found in DB.") - if not assist.session_exists(project_id=projectId, session_id=sessionId): + if not await assist.session_exists(project_id=projectId, session_id=sessionId): print(f"{projectId}/{sessionId} not found in Assist.") return not_found - path = assist.get_raw_devtools_by_id(project_id=projectId, session_id=sessionId) + path = await assist.get_raw_devtools_by_id(project_id=projectId, session_id=sessionId) if path is None: return {"errors": ["Devtools file not found"]} @@ -395,18 +395,18 @@ async def get_live_session_devtools_file(projectId: int, sessionId: Union[int, s @app.post('/{projectId}/heatmaps/url', tags=["heatmaps"]) async def get_heatmaps_by_url(projectId: int, data: schemas.GetHeatmapPayloadSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": heatmaps.get_by_url(project_id=projectId, data=data)} + return {"data": await heatmaps.get_by_url(project_id=projectId, data=data)} @app.get('/{projectId}/sessions/{sessionId}/favorite', tags=["sessions"]) async def add_remove_favorite_session2(projectId: int, sessionId: int, context: schemas.CurrentContext = Depends(OR_context)): - return sessions_favorite.favorite_session(context=context, project_id=projectId, session_id=sessionId) + return await sessions_favorite.favorite_session(context=context, project_id=projectId, session_id=sessionId) @app.get('/{projectId}/sessions/{sessionId}/assign', tags=["sessions"]) async def assign_session(projectId: int, sessionId, context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_assignments.get_by_session(project_id=projectId, session_id=sessionId, + data = await sessions_assignments.get_by_session(project_id=projectId, session_id=sessionId, tenant_id=context.tenant_id, user_id=context.user_id) if "errors" in data: @@ -419,7 +419,7 @@ async def assign_session(projectId: int, sessionId, context: schemas.CurrentCont @app.get('/{projectId}/sessions/{sessionId}/assign/{issueId}', tags=["sessions", "issueTracking"]) async def assign_session(projectId: int, sessionId: int, issueId: str, context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_assignments.get(project_id=projectId, session_id=sessionId, assignment_id=issueId, + data = await sessions_assignments.get(project_id=projectId, session_id=sessionId, assignment_id=issueId, tenant_id=context.tenant_id, user_id=context.user_id) if "errors" in data: return data @@ -432,7 +432,7 @@ async def assign_session(projectId: int, sessionId: int, issueId: str, async def comment_assignment(projectId: int, sessionId: int, issueId: str, data: schemas.CommentAssignmentSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_assignments.comment(tenant_id=context.tenant_id, project_id=projectId, + data = await sessions_assignments.comment(tenant_id=context.tenant_id, project_id=projectId, session_id=sessionId, assignment_id=issueId, user_id=context.user_id, message=data.message) if "errors" in data.keys(): @@ -445,9 +445,9 @@ async def comment_assignment(projectId: int, sessionId: int, issueId: str, @app.post('/{projectId}/sessions/{sessionId}/notes', tags=["sessions", "notes"]) async def create_note(projectId: int, sessionId: int, data: schemas.SessionNoteSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - if not sessions.session_exists(project_id=projectId, session_id=sessionId): + if not await sessions.session_exists(project_id=projectId, session_id=sessionId): return {"errors": ["Session not found"]} - data = sessions_notes.create(tenant_id=context.tenant_id, project_id=projectId, + data = await sessions_notes.create(tenant_id=context.tenant_id, project_id=projectId, session_id=sessionId, user_id=context.user_id, data=data) if "errors" in data.keys(): return data @@ -458,7 +458,7 @@ async def create_note(projectId: int, sessionId: int, data: schemas.SessionNoteS @app.get('/{projectId}/sessions/{sessionId}/notes', tags=["sessions", "notes"]) async def get_session_notes(projectId: int, sessionId: int, context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_notes.get_session_notes(tenant_id=context.tenant_id, project_id=projectId, + data = await sessions_notes.get_session_notes(tenant_id=context.tenant_id, project_id=projectId, session_id=sessionId, user_id=context.user_id) if "errors" in data: return data @@ -470,7 +470,7 @@ async def get_session_notes(projectId: int, sessionId: int, context: schemas.Cur @app.post('/{projectId}/notes/{noteId}', tags=["sessions", "notes"]) async def edit_note(projectId: int, noteId: int, data: schemas.SessionUpdateNoteSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_notes.edit(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, + data = await sessions_notes.edit(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, note_id=noteId, data=data) if "errors" in data.keys(): return data @@ -481,7 +481,7 @@ async def edit_note(projectId: int, noteId: int, data: schemas.SessionUpdateNote @app.delete('/{projectId}/notes/{noteId}', tags=["sessions", "notes"]) async def delete_note(projectId: int, noteId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_notes.delete(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, + data = await sessions_notes.delete(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, note_id=noteId) return data @@ -489,21 +489,21 @@ async def delete_note(projectId: int, noteId: int, _=Body(None), context: schema @app.get('/{projectId}/notes/{noteId}/slack/{webhookId}', tags=["sessions", "notes"]) async def share_note_to_slack(projectId: int, noteId: int, webhookId: int, context: schemas.CurrentContext = Depends(OR_context)): - return sessions_notes.share_to_slack(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, + return await sessions_notes.share_to_slack(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, note_id=noteId, webhook_id=webhookId) @app.get('/{projectId}/notes/{noteId}/msteams/{webhookId}', tags=["sessions", "notes"]) async def share_note_to_msteams(projectId: int, noteId: int, webhookId: int, context: schemas.CurrentContext = Depends(OR_context)): - return sessions_notes.share_to_msteams(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, + return await sessions_notes.share_to_msteams(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, note_id=noteId, webhook_id=webhookId) @app.post('/{projectId}/notes', tags=["sessions", "notes"]) async def get_all_notes(projectId: int, data: schemas.SearchNoteSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_notes.get_all_notes_by_project_id(tenant_id=context.tenant_id, project_id=projectId, + data = await sessions_notes.get_all_notes_by_project_id(tenant_id=context.tenant_id, project_id=projectId, user_id=context.user_id, data=data) if "errors" in data: return data @@ -513,41 +513,41 @@ async def get_all_notes(projectId: int, data: schemas.SearchNoteSchema = Body(.. @app.post('/{projectId}/click_maps/search', tags=["click maps"]) async def click_map_search(projectId: int, data: schemas.ClickMapSessionsSearch = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return {"data": click_maps.search_short_session(user_id=context.user_id, data=data, project_id=projectId)} + return {"data": await click_maps.search_short_session(user_id=context.user_id, data=data, project_id=projectId)} @app.post('/{project_id}/feature-flags/search', tags=["feature flags"]) async def search_feature_flags(project_id: int, data: schemas.SearchFlagsSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return feature_flags.search_feature_flags(project_id=project_id, user_id=context.user_id, data=data) + return await feature_flags.search_feature_flags(project_id=project_id, user_id=context.user_id, data=data) @app.get('/{project_id}/feature-flags/{feature_flag_id}', tags=["feature flags"]) async def get_feature_flag(project_id: int, feature_flag_id: int): - return feature_flags.get_feature_flag(project_id=project_id, feature_flag_id=feature_flag_id) + return await feature_flags.get_feature_flag(project_id=project_id, feature_flag_id=feature_flag_id) @app.post('/{project_id}/feature-flags', tags=["feature flags"]) async def add_feature_flag(project_id: int, data: schemas.FeatureFlagSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return feature_flags.create_feature_flag(project_id=project_id, user_id=context.user_id, feature_flag_data=data) + return await feature_flags.create_feature_flag(project_id=project_id, user_id=context.user_id, feature_flag_data=data) @app.put('/{project_id}/feature-flags/{feature_flag_id}', tags=["feature flags"]) async def update_feature_flag(project_id: int, feature_flag_id: int, data: schemas.FeatureFlagSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - return feature_flags.update_feature_flag(project_id=project_id, feature_flag_id=feature_flag_id, + return await feature_flags.update_feature_flag(project_id=project_id, feature_flag_id=feature_flag_id, user_id=context.user_id, feature_flag=data) @app.delete('/{project_id}/feature-flags/{feature_flag_id}', tags=["feature flags"]) async def delete_feature_flag(project_id: int, feature_flag_id: int, _=Body(None)): - return {"data": feature_flags.delete_feature_flag(project_id=project_id, feature_flag_id=feature_flag_id)} + return {"data": await feature_flags.delete_feature_flag(project_id=project_id, feature_flag_id=feature_flag_id)} @app.post('/{project_id}/feature-flags/{feature_flag_id}/status', tags=["feature flags"]) async def update_feature_flag_status(project_id: int, feature_flag_id: int, data: schemas.FeatureFlagStatus = Body(...)): - return {"data": feature_flags.update_feature_flag_status(project_id=project_id, feature_flag_id=feature_flag_id, + return {"data": await feature_flags.update_feature_flag_status(project_id=project_id, feature_flag_id=feature_flag_id, is_active=data.is_active)}