diff --git a/api/.gitignore b/api/.gitignore index dd32b5d3f..6a46fedcb 100644 --- a/api/.gitignore +++ b/api/.gitignore @@ -83,6 +83,7 @@ wheels/ .installed.cfg *.egg MANIFEST +Pipfile # PyInstaller # Usually these files are written by a python script from a template diff --git a/api/app.py b/api/app.py index 2c4465189..254f980ba 100644 --- a/api/app.py +++ b/api/app.py @@ -4,7 +4,7 @@ from sentry_sdk import configure_scope from chalicelib import _overrides from chalicelib.blueprints import bp_authorizers -from chalicelib.blueprints import bp_core, bp_core_crons +from chalicelib.blueprints import bp_core, bp_core_crons, bp_app_api from chalicelib.blueprints import bp_core_dynamic, bp_core_dynamic_crons from chalicelib.blueprints.subs import bp_dashboard from chalicelib.utils import helper @@ -99,3 +99,5 @@ app.register_blueprint(bp_core_crons.app) app.register_blueprint(bp_core_dynamic.app) app.register_blueprint(bp_core_dynamic_crons.app) app.register_blueprint(bp_dashboard.app) +app.register_blueprint(bp_app_api.app) + diff --git a/api/chalicelib/blueprints/bp_app_api.py b/api/chalicelib/blueprints/bp_app_api.py new file mode 100644 index 000000000..47a492808 --- /dev/null +++ b/api/chalicelib/blueprints/bp_app_api.py @@ -0,0 +1,55 @@ +from chalice import Blueprint + +from chalicelib import _overrides +from chalicelib.blueprints import bp_authorizers +from chalicelib.core import sessions + +app = Blueprint(__name__) +_overrides.chalice_app(app) + + +@app.route('/app/{projectId}/users/{userId}/sessions', methods=['GET'], authorizer=bp_authorizers.api_key_authorizer) +def get_user_sessions2(projectId, userId, context): + params = app.current_request.query_params + + if params is None: + params = {} + + return { + 'data': sessions.get_user_sessions( + project_id=projectId, + user_id=userId, + start_date=params.get('start_date'), + end_date=params.get('end_date') + ) + } + + +@app.route('/app/{projectId}/users/{userId}/events', methods=['GET'], authorizer=bp_authorizers.api_key_authorizer) +def get_user_events(): + pass + + +@app.route('/app/{projectId}/users/{userId}', methods=['GET'], authorizer=bp_authorizers.api_key_authorizer) +def get_user_details(): + pass + + +@app.route('/app/{projectId}/users/{userId}', methods=['DELETE'], authorizer=bp_authorizers.api_key_authorizer) +def delete_user_data(): + pass + + +@app.route('/app/{projectId}/jobs', methods=['GET'], authorizer=bp_authorizers.api_key_authorizer) +def get_jobs(): + pass + + +@app.route('/app/{projectId}/jobs/{jobId}', methods=['GET'], authorizer=bp_authorizers.api_key_authorizer) +def get_job(): + pass + + +@app.route('/app/{projectId}/jobs/{jobId}', methods=['DELETE'], authorizer=bp_authorizers.api_key_authorizer) +def cancel_job(): + pass diff --git a/api/chalicelib/core/sessions.py b/api/chalicelib/core/sessions.py index fa127b04a..61e42636b 100644 --- a/api/chalicelib/core/sessions.py +++ b/api/chalicelib/core/sessions.py @@ -617,3 +617,43 @@ def get_favorite_sessions(project_id, user_id, include_viewed=False): sessions = cur.fetchall() return helper.list_to_camel_case(sessions) + + +def get_user_sessions(project_id, user_id, start_date, end_date): + with pg_client.PostgresClient() as cur: + constraints = ["s.project_id = %(projectId)s", "s.user_id = %(userId)s"] + if start_date is not None: + constraints.append("s.start_ts >= %(startDate)s") + if end_date is not None: + constraints.append("s.start_ts <= %(endDate)s") + + query_part = f"""\ + FROM public.sessions AS s + WHERE {" AND ".join(constraints)}""" + + cur.execute(cur.mogrify(f"""\ + SELECT s.project_id, + s.session_id::text AS session_id, + s.user_uuid, + s.user_id, + s.user_agent, + s.user_os, + s.user_browser, + s.user_device, + s.user_country, + s.start_ts, + s.duration, + s.events_count, + s.pages_count, + s.errors_count + {query_part} + ORDER BY s.session_id + LIMIT 50;""", { + "projectId": project_id, + "userId": user_id, + "startDate": start_date, + "endDate": end_date + })) + + sessions = cur.fetchall() + return helper.list_to_camel_case(sessions)