From 437fe9533bac574891f32d82af959c5e7dc11a74 Mon Sep 17 00:00:00 2001 From: Kraiem Taha Yassine Date: Fri, 27 Oct 2023 14:35:16 +0200 Subject: [PATCH] Api v1.15.0 (#1580) * fix(chalice): fixed public API refactor(chalice): changed path logging refactor(chalice): refactored public API --- api/auth/auth_apikey.py | 2 +- api/chalicelib/core/jobs.py | 7 +-- api/or_dependencies.py | 8 +++- api/routers/core.py | 8 ++-- api/routers/subs/v1_api.py | 47 +++++++------------ ee/api/chalicelib/core/traces.py | 1 - ee/api/or_dependencies.py | 6 ++- ee/api/routers/subs/v1_api_ee.py | 11 +---- .../db/init_dbs/postgresql/1.15.0/1.15.0.sql | 1 + .../db/init_dbs/postgresql/init_schema.sql | 1 + 10 files changed, 40 insertions(+), 52 deletions(-) diff --git a/api/auth/auth_apikey.py b/api/auth/auth_apikey.py index 6a784fd5f..0171da436 100644 --- a/api/auth/auth_apikey.py +++ b/api/auth/auth_apikey.py @@ -27,5 +27,5 @@ class APIKeyAuth(APIKeyHeader): r["authorizer_identity"] = "api_key" logger.debug(r) request.state.authorizer_identity = "api_key" - request.state.currentContext = CurrentAPIContext(tenant_id=r["tenantId"]) + request.state.currentContext = CurrentAPIContext(tenantId=r["tenantId"]) return request.state.currentContext diff --git a/api/chalicelib/core/jobs.py b/api/chalicelib/core/jobs.py index 0842c4de7..36c547455 100644 --- a/api/chalicelib/core/jobs.py +++ b/api/chalicelib/core/jobs.py @@ -14,13 +14,14 @@ class JobStatus: CANCELLED = "cancelled" -def get(job_id): +def get(job_id, project_id): with pg_client.PostgresClient() as cur: query = cur.mogrify( """SELECT * FROM public.jobs - WHERE job_id = %(job_id)s;""", - {"job_id": job_id} + WHERE job_id = %(job_id)s + AND project_id= %(project_id)s;""", + {"job_id": job_id, "project_id": project_id} ) cur.execute(query=query) data = cur.fetchone() diff --git a/api/or_dependencies.py b/api/or_dependencies.py index 5cfab1138..2a192550b 100644 --- a/api/or_dependencies.py +++ b/api/or_dependencies.py @@ -1,17 +1,20 @@ import json +import logging from typing import Callable +from fastapi import Depends, Security from fastapi.routing import APIRoute +from fastapi.security import SecurityScopes from starlette import status from starlette.exceptions import HTTPException from starlette.requests import Request from starlette.responses import Response, JSONResponse -from fastapi.security import SecurityScopes -from fastapi import Depends, Security import schemas from chalicelib.utils import helper +logger = logging.getLogger(__name__) + async def OR_context(request: Request) -> schemas.CurrentContext: if hasattr(request.state, "currentContext"): @@ -25,6 +28,7 @@ class ORRoute(APIRoute): original_route_handler = super().get_route_handler() async def custom_route_handler(request: Request) -> Response: + logger.debug(f"call processed by: {self.methods} {self.path_format}") try: response: Response = await original_route_handler(request) except HTTPException as e: diff --git a/api/routers/core.py b/api/routers/core.py index 1225b8d8e..22438cd4b 100644 --- a/api/routers/core.py +++ b/api/routers/core.py @@ -1,9 +1,7 @@ -import json -from datetime import datetime, timedelta -from typing import Union, List, Dict, Optional +from typing import Union, Optional + from decouple import config -from fastapi import Depends, Body, Query, HTTPException -from starlette.responses import FileResponse +from fastapi import Depends, Body, Query import schemas from chalicelib.core import log_tool_rollbar, sourcemaps, events, sessions_assignments, projects, \ diff --git a/api/routers/subs/v1_api.py b/api/routers/subs/v1_api.py index 7b5e54047..b4e9c2aaa 100644 --- a/api/routers/subs/v1_api.py +++ b/api/routers/subs/v1_api.py @@ -9,13 +9,11 @@ public_app, app, app_apikey = get_routers() @app_apikey.get('/v1/{projectKey}/users/{userId}/sessions', tags=["api"]) -def get_user_sessions(projectKey: str, userId: str, start_date: int = None, end_date: int = None): - projectId = projects.get_by_project_key(project_key=projectKey)["projectId"] - if projectId is None: - return {"errors": ["invalid projectKey"]} +def get_user_sessions(projectKey: str, userId: str, start_date: int = None, end_date: int = None, + context: schemas.CurrentContext = Depends(OR_context)): return { "data": sessions.get_user_sessions( - project_id=projectId, + project_id=context.project.project_id, user_id=userId, start_date=start_date, end_date=end_date @@ -24,56 +22,45 @@ def get_user_sessions(projectKey: str, userId: str, start_date: int = None, end_ @app_apikey.get('/v1/{projectKey}/sessions/{sessionId}/events', tags=["api"]) -def get_session_events(projectKey: str, sessionId: int): - projectId = projects.get_by_project_key(project_key=projectKey)["projectId"] - if projectId is None: - return {"errors": ["invalid projectKey"]} +def get_session_events(projectKey: str, sessionId: int, context: schemas.CurrentContext = Depends(OR_context)): return { "data": events.get_by_session_id( - project_id=projectId, + project_id=context.project.project_id, session_id=sessionId ) } @app_apikey.get('/v1/{projectKey}/users/{userId}', tags=["api"]) -def get_user_details(projectKey: str, userId: str): - projectId = projects.get_by_project_key(project_key=projectKey)["projectId"] - if projectId is None: - return {"errors": ["invalid projectKey"]} +def get_user_details(projectKey: str, userId: str, context: schemas.CurrentContext = Depends(OR_context)): return { "data": sessions.get_session_user( - project_id=projectId, + project_id=context.project.project_id, user_id=userId ) } @app_apikey.delete('/v1/{projectKey}/users/{userId}', tags=["api"]) -def schedule_to_delete_user_data(projectKey: str, userId: str, _=Body(None)): - projectId = projects.get_by_project_key(project_key=projectKey)["projectId"] - if projectId is None: - return {"errors": ["invalid projectKey"]} - record = jobs.create(project_id=projectId, user_id=userId) +def schedule_to_delete_user_data(projectKey: str, userId: str, _=Body(None), + context: schemas.CurrentContext = Depends(OR_context)): + record = jobs.create(project_id=context.project.project_id, user_id=userId) return {"data": record} @app_apikey.get('/v1/{projectKey}/jobs', tags=["api"]) -def get_jobs(projectKey: str): - projectId = projects.get_by_project_key(project_key=projectKey)["projectId"] - if projectId is None: - return {"errors": ["invalid projectKey"]} - return {"data": jobs.get_all(project_id=projectId)} +def get_jobs(projectKey: str, context: schemas.CurrentContext = Depends(OR_context)): + return {"data": jobs.get_all(project_id=context.project.project_id)} @app_apikey.get('/v1/{projectKey}/jobs/{jobId}', tags=["api"]) -def get_job(projectKey: str, jobId: int): - return {"data": jobs.get(job_id=jobId)} +def get_job(projectKey: str, jobId: int, context: schemas.CurrentContext = Depends(OR_context)): + return {"data": jobs.get(job_id=jobId, project_id=context.project.project_id)} @app_apikey.delete('/v1/{projectKey}/jobs/{jobId}', tags=["api"]) -def cancel_job(projectKey: str, jobId: int, _=Body(None)): - job = jobs.get(job_id=jobId) +def cancel_job(projectKey: str, jobId: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): + job = jobs.get(job_id=jobId, project_id=context.project.project_id) job_not_found = len(job.keys()) == 0 if job_not_found: @@ -97,7 +84,7 @@ def get_projects(context: schemas.CurrentContext = Depends(OR_context)): @app_apikey.get('/v1/projects/{projectKey}', tags=["api"]) def get_project(projectKey: str, context: schemas.CurrentContext = Depends(OR_context)): return { - "data": projects.get_by_project_key(tenant_id=context.tenant_id, project_key=projectKey) + "data": projects.get_by_project_key(project_key=projectKey) } diff --git a/ee/api/chalicelib/core/traces.py b/ee/api/chalicelib/core/traces.py index f968183ff..ca9f707b6 100644 --- a/ee/api/chalicelib/core/traces.py +++ b/ee/api/chalicelib/core/traces.py @@ -10,7 +10,6 @@ from starlette.background import BackgroundTask import app as main_app import schemas -import schemas from chalicelib.utils import pg_client, helper from chalicelib.utils.TimeUTC import TimeUTC from schemas import CurrentContext diff --git a/ee/api/or_dependencies.py b/ee/api/or_dependencies.py index 87189bcfa..856cea13b 100644 --- a/ee/api/or_dependencies.py +++ b/ee/api/or_dependencies.py @@ -1,4 +1,5 @@ import json +import logging from typing import Callable from fastapi import HTTPException, Depends @@ -11,8 +12,10 @@ from starlette.requests import Request from starlette.responses import Response, JSONResponse import schemas -from chalicelib.utils import helper from chalicelib.core import traces +from chalicelib.utils import helper + +logger = logging.getLogger(__name__) async def OR_context(request: Request) -> schemas.CurrentContext: @@ -27,6 +30,7 @@ class ORRoute(APIRoute): original_route_handler = super().get_route_handler() async def custom_route_handler(request: Request) -> Response: + logger.debug(f"call processed by: {self.methods} {self.path_format}") try: response: Response = await original_route_handler(request) except HTTPException as e: diff --git a/ee/api/routers/subs/v1_api_ee.py b/ee/api/routers/subs/v1_api_ee.py index 47a68f4b8..c962fbf02 100644 --- a/ee/api/routers/subs/v1_api_ee.py +++ b/ee/api/routers/subs/v1_api_ee.py @@ -2,7 +2,6 @@ from fastapi import Depends, Body import schemas from chalicelib.utils import assist_helper -from chalicelib.core import projects from or_dependencies import OR_context from routers import core from routers.base import get_routers @@ -20,16 +19,10 @@ def get_assist_credentials(): @app_apikey.get('/v1/{projectKey}/assist/sessions', tags=["api"]) def get_sessions_live(projectKey: str, userId: str = None, context: schemas.CurrentContext = Depends(OR_context)): - projectId = projects.get_by_project_key(projectKey) - if projectId is None: - return {"errors": ["invalid projectKey"]} - return core.get_sessions_live(projectId=projectId, userId=userId, context=context) + return core.get_sessions_live(projectId=context.project.project_id, userId=userId, context=context) @app_apikey.post('/v1/{projectKey}/assist/sessions', tags=["api"]) def sessions_live(projectKey: str, data: schemas.LiveSessionsSearchPayloadSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): - projectId = projects.get_by_project_key(projectKey) - if projectId is None: - return {"errors": ["invalid projectKey"]} - return core.sessions_live(projectId=projectId, data=data, context=context) + return core.sessions_live(projectId=context.project.project_id, data=data, context=context) diff --git a/ee/scripts/schema/db/init_dbs/postgresql/1.15.0/1.15.0.sql b/ee/scripts/schema/db/init_dbs/postgresql/1.15.0/1.15.0.sql index 0eb63f572..f11897d53 100644 --- a/ee/scripts/schema/db/init_dbs/postgresql/1.15.0/1.15.0.sql +++ b/ee/scripts/schema/db/init_dbs/postgresql/1.15.0/1.15.0.sql @@ -131,6 +131,7 @@ CREATE TABLE IF NOT EXISTS public.assist_events event_state varchar NOT NULL, timestamp integer NOT NULL, user_id varchar, + duration integer, agent_id varchar ); diff --git a/ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql b/ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql index 703f43090..6af6d9517 100644 --- a/ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql +++ b/ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql @@ -980,6 +980,7 @@ $$ event_state varchar NOT NULL, timestamp integer NOT NULL, user_id varchar, + duration integer, agent_id varchar );