from chalicelib.utils.helper import environ from chalice import Blueprint from chalice import Response from chalicelib import _overrides from chalicelib.blueprints import bp_authorizers from chalicelib.core import log_tool_rollbar, sourcemaps, events, sessions_assignments, projects, \ sessions_metas, alerts, funnels, issues, integrations_manager, errors_favorite_viewed, metadata, \ log_tool_elasticsearch, log_tool_datadog, \ log_tool_stackdriver, reset_password, sessions_favorite_viewed, \ log_tool_cloudwatch, log_tool_sentry, log_tool_sumologic, log_tools, errors, sessions, \ log_tool_newrelic, announcements, log_tool_bugsnag, weekly_report, integration_jira_cloud, integration_github, \ assist, heatmaps from chalicelib.core.collaboration_slack import Slack from chalicelib.utils import email_helper app = Blueprint(__name__) _overrides.chalice_app(app) @app.route('/{projectId}/sessions2/favorite', methods=['GET']) def get_favorite_sessions2(projectId, context): params = app.current_request.query_params return { 'data': sessions.get_favorite_sessions(project_id=projectId, user_id=context["userId"], include_viewed=True) } @app.route('/{projectId}/sessions2/{sessionId}', methods=['GET']) def get_session2(projectId, sessionId, context): data = sessions.get_by_id2_pg(project_id=projectId, session_id=sessionId, full_data=True, user_id=context["userId"], include_fav_viewed=True, group_metadata=True) if data is None: return {"errors": ["session not found"]} sessions_favorite_viewed.view_session(project_id=projectId, user_id=context['userId'], session_id=sessionId) return { 'data': data } @app.route('/{projectId}/sessions2/{sessionId}/favorite', methods=['GET']) def add_remove_favorite_session2(projectId, sessionId, context): return { "data": sessions_favorite_viewed.favorite_session(project_id=projectId, user_id=context['userId'], session_id=sessionId)} @app.route('/{projectId}/sessions2/{sessionId}/assign', methods=['GET']) def assign_session(projectId, sessionId, context): data = sessions_assignments.get_by_session(project_id=projectId, session_id=sessionId, tenant_id=context['tenantId'], user_id=context["userId"]) if "errors" in data: return data return { 'data': data } @app.route('/{projectId}/sessions2/{sessionId}/errors/{errorId}/sourcemaps', methods=['GET']) def get_error_trace(projectId, sessionId, errorId, context): data = errors.get_trace(project_id=projectId, error_id=errorId) if "errors" in data: return data return { 'data': data } @app.route('/{projectId}/sessions2/{sessionId}/assign/{issueId}', methods=['GET']) def assign_session(projectId, sessionId, issueId, context): data = sessions_assignments.get(project_id=projectId, session_id=sessionId, assignment_id=issueId, tenant_id=context['tenantId'], user_id=context["userId"]) if "errors" in data: return data return { 'data': data } @app.route('/{projectId}/sessions2/{sessionId}/assign/{issueId}/comment', methods=['POST', 'PUT']) def comment_assignment(projectId, sessionId, issueId, context): data = app.current_request.json_body data = sessions_assignments.comment(tenant_id=context['tenantId'], project_id=projectId, session_id=sessionId, assignment_id=issueId, user_id=context["userId"], message=data["message"]) if "errors" in data.keys(): return data return { 'data': data } @app.route('/{projectId}/events/search', methods=['GET']) def events_search(projectId, context): params = app.current_request.query_params if params is None: return {"data": []} q = params.get('q', '') if len(q) == 0: return {"data": []} result = events.search_pg2(q, params.get('type', ''), project_id=projectId, source=params.get('source'), key=params.get("key")) return result @app.route('/{projectId}/sessions/search2', methods=['POST']) def sessions_search2(projectId, context): data = app.current_request.json_body data = sessions.search2_pg(data, projectId, user_id=context["userId"]) return {'data': data} @app.route('/{projectId}/sessions/filters', methods=['GET']) def session_filter_values(projectId, context): return {'data': sessions_metas.get_key_values(projectId)} @app.route('/{projectId}/sessions/filters/top', methods=['GET']) def session_top_filter_values(projectId, context): return {'data': sessions_metas.get_top_key_values(projectId)} @app.route('/{projectId}/sessions/filters/search', methods=['GET']) def get_session_filters_meta(projectId, context): params = app.current_request.query_params if params is None: return {"data": []} meta_type = params.get('type', '') if len(meta_type) == 0: return {"data": []} q = params.get('q', '') if len(q) == 0: return {"data": []} return sessions_metas.search(project_id=projectId, meta_type=meta_type, text=q) @app.route('/{projectId}/integrations/{integration}/notify/{integrationId}/{source}/{sourceId}', methods=['POST', 'PUT']) def integration_notify(projectId, integration, integrationId, source, sourceId, context): data = app.current_request.json_body comment = None if "comment" in data: comment = data["comment"] if integration == "slack": args = {"tenant_id": context["tenantId"], "user": context['email'], "comment": comment, "project_id": projectId, "integration_id": integrationId} if source == "sessions": return Slack.share_session(session_id=sourceId, **args) elif source == "errors": return Slack.share_error(error_id=sourceId, **args) return {"data": None} @app.route('/integrations/sentry', methods=['GET']) def get_all_sentry(context): return {"data": log_tool_sentry.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/sentry', methods=['GET']) def get_sentry(projectId, context): return {"data": log_tool_sentry.get(project_id=projectId)} @app.route('/{projectId}/integrations/sentry', methods=['POST', 'PUT']) def add_edit_sentry(projectId, context): data = app.current_request.json_body return {"data": log_tool_sentry.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/sentry', methods=['DELETE']) def delete_sentry(projectId, context): return {"data": log_tool_sentry.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/{projectId}/integrations/sentry/events/{eventId}', methods=['GET']) def proxy_sentry(projectId, eventId, context): return {"data": log_tool_sentry.proxy_get(tenant_id=context["tenantId"], project_id=projectId, event_id=eventId)} @app.route('/integrations/datadog', methods=['GET']) def get_all_datadog(context): return {"data": log_tool_datadog.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/datadog', methods=['GET']) def get_datadog(projectId, context): return {"data": log_tool_datadog.get(project_id=projectId)} @app.route('/{projectId}/integrations/datadog', methods=['POST', 'PUT']) def add_edit_datadog(projectId, context): data = app.current_request.json_body return {"data": log_tool_datadog.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/datadog', methods=['DELETE']) def delete_datadog(projectId, context): return {"data": log_tool_datadog.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/integrations/stackdriver', methods=['GET']) def get_all_stackdriver(context): return {"data": log_tool_stackdriver.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/stackdriver', methods=['GET']) def get_stackdriver(projectId, context): return {"data": log_tool_stackdriver.get(project_id=projectId)} @app.route('/{projectId}/integrations/stackdriver', methods=['POST', 'PUT']) def add_edit_stackdriver(projectId, context): data = app.current_request.json_body return {"data": log_tool_stackdriver.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/stackdriver', methods=['DELETE']) def delete_stackdriver(projectId, context): return {"data": log_tool_stackdriver.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/integrations/newrelic', methods=['GET']) def get_all_newrelic(context): return {"data": log_tool_newrelic.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/newrelic', methods=['GET']) def get_newrelic(projectId, context): return {"data": log_tool_newrelic.get(project_id=projectId)} @app.route('/{projectId}/integrations/newrelic', methods=['POST', 'PUT']) def add_edit_newrelic(projectId, context): data = app.current_request.json_body return {"data": log_tool_newrelic.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/newrelic', methods=['DELETE']) def delete_newrelic(projectId, context): return {"data": log_tool_newrelic.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/integrations/rollbar', methods=['GET']) def get_all_rollbar(context): return {"data": log_tool_rollbar.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/rollbar', methods=['GET']) def get_rollbar(projectId, context): return {"data": log_tool_rollbar.get(project_id=projectId)} @app.route('/{projectId}/integrations/rollbar', methods=['POST', 'PUT']) def add_edit_rollbar(projectId, context): data = app.current_request.json_body return {"data": log_tool_rollbar.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/rollbar', methods=['DELETE']) def delete_datadog(projectId, context): return {"data": log_tool_rollbar.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/integrations/bugsnag/list_projects', methods=['POST']) def list_projects_bugsnag(context): data = app.current_request.json_body return {"data": log_tool_bugsnag.list_projects(auth_token=data["authorizationToken"])} @app.route('/integrations/bugsnag', methods=['GET']) def get_all_bugsnag(context): return {"data": log_tool_bugsnag.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/bugsnag', methods=['GET']) def get_bugsnag(projectId, context): return {"data": log_tool_bugsnag.get(project_id=projectId)} @app.route('/{projectId}/integrations/bugsnag', methods=['POST', 'PUT']) def add_edit_bugsnag(projectId, context): data = app.current_request.json_body return {"data": log_tool_bugsnag.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/bugsnag', methods=['DELETE']) def delete_bugsnag(projectId, context): return {"data": log_tool_bugsnag.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/integrations/cloudwatch/list_groups', methods=['POST']) def list_groups_cloudwatch(context): data = app.current_request.json_body return {"data": log_tool_cloudwatch.list_log_groups(aws_access_key_id=data["awsAccessKeyId"], aws_secret_access_key=data["awsSecretAccessKey"], region=data["region"])} @app.route('/integrations/cloudwatch', methods=['GET']) def get_all_cloudwatch(context): return {"data": log_tool_cloudwatch.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/cloudwatch', methods=['GET']) def get_cloudwatch(projectId, context): return {"data": log_tool_cloudwatch.get(project_id=projectId)} @app.route('/{projectId}/integrations/cloudwatch', methods=['POST', 'PUT']) def add_edit_cloudwatch(projectId, context): data = app.current_request.json_body return {"data": log_tool_cloudwatch.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/cloudwatch', methods=['DELETE']) def delete_cloudwatch(projectId, context): return {"data": log_tool_cloudwatch.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/integrations/elasticsearch', methods=['GET']) def get_all_elasticsearch(context): return {"data": log_tool_elasticsearch.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/elasticsearch', methods=['GET']) def get_elasticsearch(projectId, context): return {"data": log_tool_elasticsearch.get(project_id=projectId)} @app.route('/integrations/elasticsearch/test', methods=['POST']) def test_elasticsearch_connection(context): data = app.current_request.json_body return {"data": log_tool_elasticsearch.ping(tenant_id=context["tenantId"], **data)} @app.route('/{projectId}/integrations/elasticsearch', methods=['POST', 'PUT']) def add_edit_elasticsearch(projectId, context): data = app.current_request.json_body return {"data": log_tool_elasticsearch.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/elasticsearch', methods=['DELETE']) def delete_elasticsearch(projectId, context): return {"data": log_tool_elasticsearch.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/integrations/sumologic', methods=['GET']) def get_all_sumologic(context): return {"data": log_tool_sumologic.get_all(tenant_id=context["tenantId"])} @app.route('/{projectId}/integrations/sumologic', methods=['GET']) def get_sumologic(projectId, context): return {"data": log_tool_sumologic.get(project_id=projectId)} @app.route('/{projectId}/integrations/sumologic', methods=['POST', 'PUT']) def add_edit_sumologic(projectId, context): data = app.current_request.json_body return {"data": log_tool_sumologic.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)} @app.route('/{projectId}/integrations/sumologic', methods=['DELETE']) def delete_sumologic(projectId, context): return {"data": log_tool_sumologic.delete(tenant_id=context["tenantId"], project_id=projectId)} @app.route('/integrations/issues', methods=['GET']) def get_integration_status(context): error, integration = integrations_manager.get_integration(tenant_id=context["tenantId"], user_id=context["userId"]) if error is not None: return {"data": {}} return {"data": integration.get_obfuscated()} @app.route('/integrations/jira', methods=['POST', 'PUT']) def add_edit_jira_cloud(context): data = app.current_request.json_body error, integration = integrations_manager.get_integration(tool=integration_jira_cloud.PROVIDER, tenant_id=context["tenantId"], user_id=context["userId"]) if error is not None: return error return {"data": integration.add_edit(data=data)} @app.route('/integrations/github', methods=['POST', 'PUT']) def add_edit_github(context): data = app.current_request.json_body error, integration = integrations_manager.get_integration(tool=integration_github.PROVIDER, tenant_id=context["tenantId"], user_id=context["userId"]) if error is not None: return error return {"data": integration.add_edit(data=data)} @app.route('/integrations/issues', methods=['DELETE']) def delete_default_issue_tracking_tool(context): error, integration = integrations_manager.get_integration(tenant_id=context["tenantId"], user_id=context["userId"]) if error is not None: return error return {"data": integration.delete()} @app.route('/integrations/jira', methods=['DELETE']) def delete_jira_cloud(context): error, integration = integrations_manager.get_integration(tool=integration_jira_cloud.PROVIDER, tenant_id=context["tenantId"], user_id=context["userId"]) if error is not None: return error return {"data": integration.delete()} @app.route('/integrations/github', methods=['DELETE']) def delete_github(context): error, integration = integrations_manager.get_integration(tool=integration_github.PROVIDER, tenant_id=context["tenantId"], user_id=context["userId"]) if error is not None: return error return {"data": integration.delete()} @app.route('/integrations/issues/list_projects', methods=['GET']) def get_all_issue_tracking_projects(context): error, integration = integrations_manager.get_integration(tenant_id=context["tenantId"], user_id=context["userId"]) if error is not None: return error data = integration.issue_handler.get_projects() if "errors" in data: return data return {"data": data} @app.route('/integrations/issues/{integrationProjectId}', methods=['GET']) def get_integration_metadata(integrationProjectId, context): error, integration = integrations_manager.get_integration(tenant_id=context["tenantId"], user_id=context["userId"]) if error is not None: return error data = integration.issue_handler.get_metas(integrationProjectId) if "errors" in data.keys(): return data return {"data": data} @app.route('/{projectId}/assignments', methods=['GET']) def get_all_assignments(projectId, context): data = sessions_assignments.get_all(project_id=projectId, user_id=context["userId"]) return { 'data': data } @app.route('/{projectId}/sessions2/{sessionId}/assign/projects/{integrationProjectId}', methods=['POST', 'PUT']) def create_issue_assignment(projectId, sessionId, integrationProjectId, context): data = app.current_request.json_body data = sessions_assignments.create_new_assignment(tenant_id=context['tenantId'], project_id=projectId, session_id=sessionId, creator_id=context["userId"], assignee=data["assignee"], description=data["description"], title=data["title"], issue_type=data["issueType"], integration_project_id=integrationProjectId) if "errors" in data.keys(): return data return { 'data': data } @app.route('/{projectId}/gdpr', methods=['GET']) def get_gdpr(projectId, context): return {"data": projects.get_gdpr(project_id=projectId)} @app.route('/{projectId}/gdpr', methods=['POST', 'PUT']) def edit_gdpr(projectId, context): data = app.current_request.json_body return {"data": projects.edit_gdpr(project_id=projectId, gdpr=data)} @app.route('/password/reset-link', methods=['PUT', 'POST'], authorizer=None) def reset_password_handler(): data = app.current_request.json_body if "email" not in data or len(data["email"]) < 5: return {"errors": ["please provide a valid email address"]} return reset_password.reset(data) @app.route('/{projectId}/metadata', methods=['GET']) def get_metadata(projectId, context): return {"data": metadata.get(project_id=projectId)} @app.route('/{projectId}/metadata/list', methods=['POST', 'PUT']) def add_edit_delete_metadata(projectId, context): data = app.current_request.json_body return metadata.add_edit_delete(tenant_id=context["tenantId"], project_id=projectId, new_metas=data["list"]) @app.route('/{projectId}/metadata', methods=['POST', 'PUT']) def add_metadata(projectId, context): data = app.current_request.json_body return metadata.add(tenant_id=context["tenantId"], project_id=projectId, new_name=data["key"]) @app.route('/{projectId}/metadata/{index}', methods=['POST', 'PUT']) def edit_metadata(projectId, index, context): data = app.current_request.json_body return metadata.edit(tenant_id=context["tenantId"], project_id=projectId, index=int(index), new_name=data["key"]) @app.route('/{projectId}/metadata/{index}', methods=['DELETE']) def delete_metadata(projectId, index, context): return metadata.delete(tenant_id=context["tenantId"], project_id=projectId, index=index) @app.route('/{projectId}/metadata/search', methods=['GET']) def search_metadata(projectId, context): params = app.current_request.query_params q = params.get('q', '') key = params.get('key', '') if len(q) == 0 and len(key) == 0: return {"data": []} if len(q) == 0: 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["tenantId"], project_id=projectId, value=q, key=key) @app.route('/{projectId}/integration/sources', methods=['GET']) def search_integrations(projectId, context): return log_tools.search(project_id=projectId) @app.route('/async/email_assignment', methods=['POST', 'PUT'], authorizer=None) def async_send_signup_emails(): data = app.current_request.json_body if data.pop("auth") != environ["async_Token"]: return {} email_helper.send_assign_session(recipient=data["email"], link=data["link"], message=data["message"]) @app.route('/async/funnel/weekly_report2', methods=['POST', 'PUT'], authorizer=None) def async_weekly_report(): print("=========================> Sending weekly report") data = app.current_request.json_body if data.pop("auth") != environ["async_Token"]: return {} email_helper.weekly_report2(recipients=data["email"], data=data.get("data", None)) @app.route('/async/basic/{step}', methods=['POST', 'PUT'], authorizer=None) def async_basic_emails(step): data = app.current_request.json_body if data.pop("auth") != environ["async_Token"]: return {} if step.lower() == "member_invitation": email_helper.send_team_invitation(recipient=data["email"], invitation_link=data["invitationLink"], client_id=data["clientId"], sender_name=data["senderName"]) @app.route('/{projectId}/sample_rate', methods=['GET']) def get_capture_status(projectId, context): return {"data": projects.get_capture_status(project_id=projectId)} @app.route('/{projectId}/sample_rate', methods=['POST', 'PUT']) def update_capture_status(projectId, context): data = app.current_request.json_body return {"data": projects.update_capture_status(project_id=projectId, changes=data)} @app.route('/announcements', methods=['GET']) def get_all_announcements(context): return {"data": announcements.get_all(context["userId"])} @app.route('/announcements/view', methods=['GET']) def get_all_announcements(context): return {"data": announcements.view(user_id=context["userId"])} @app.route('/{projectId}/errors/{errorId}/{action}', methods=['GET']) def add_remove_favorite_error(projectId, errorId, action, context): if action == "favorite": return errors_favorite_viewed.favorite_error(project_id=projectId, user_id=context['userId'], error_id=errorId) elif action == "sessions": params = app.current_request.query_params if params is None: params = {} start_date = params.get("startDate") end_date = params.get("endDate") return { "data": errors.get_sessions(project_id=projectId, user_id=context['userId'], 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['userId'], error_id=errorId, action=action) else: return {"errors": ["undefined action"]} @app.route('/{projectId}/errors/merge', methods=['POST']) def errors_merge(projectId, context): data = app.current_request.json_body data = errors.merge(error_ids=data.get("errors", [])) return data @app.route('/show_banner', methods=['GET']) def errors_merge(context): return {"data": False} @app.route('/{projectId}/alerts', methods=['POST', 'PUT']) def create_alert(projectId, context): data = app.current_request.json_body return alerts.create(projectId, data) @app.route('/{projectId}/alerts', methods=['GET']) def get_all_alerts(projectId, context): return {"data": alerts.get_all(projectId)} @app.route('/{projectId}/alerts/{alertId}', methods=['GET']) def get_alert(projectId, alertId, context): return {"data": alerts.get(alertId)} @app.route('/{projectId}/alerts/{alertId}', methods=['POST', 'PUT']) def update_alert(projectId, alertId, context): data = app.current_request.json_body return alerts.update(alertId, data) @app.route('/{projectId}/alerts/{alertId}', methods=['DELETE']) def delete_alert(projectId, alertId, context): return alerts.delete(projectId, alertId) @app.route('/{projectId}/funnels', methods=['POST', 'PUT']) def add_funnel(projectId, context): data = app.current_request.json_body return funnels.create(project_id=projectId, user_id=context['userId'], name=data["name"], filter=data["filter"], is_public=data.get("isPublic", False)) @app.route('/{projectId}/funnels', methods=['GET']) def get_funnels(projectId, context): params = app.current_request.query_params if params is None: params = {} return {"data": funnels.get_by_user(project_id=projectId, user_id=context['userId'], range_value=None, start_date=None, end_date=None, details=False)} @app.route('/{projectId}/funnels/details', methods=['GET']) def get_funnels_with_details(projectId, context): params = app.current_request.query_params if params is None: params = {} return {"data": funnels.get_by_user(project_id=projectId, user_id=context['userId'], range_value=params.get("rangeValue", None), start_date=params.get('startDate', None), end_date=params.get('endDate', None), details=True)} @app.route('/{projectId}/funnels/issue_types', methods=['GET']) def get_possible_issue_types(projectId, context): params = app.current_request.query_params if params is None: params = {} return {"data": funnels.get_possible_issue_types(project_id=projectId)} @app.route('/{projectId}/funnels/{funnelId}/insights', methods=['GET']) def get_funnel_insights(projectId, funnelId, context): params = app.current_request.query_params if params is None: params = {} return funnels.get_top_insights(funnel_id=funnelId, project_id=projectId, range_value=params.get("range_value", None), start_date=params.get('startDate', None), end_date=params.get('endDate', None)) @app.route('/{projectId}/funnels/{funnelId}/insights', methods=['POST', 'PUT']) def get_funnel_insights_on_the_fly(projectId, funnelId, context): params = app.current_request.query_params if params is None: params = {} data = app.current_request.json_body if data is None: data = {} return funnels.get_top_insights_on_the_fly(funnel_id=funnelId, project_id=projectId, data={**params, **data}) @app.route('/{projectId}/funnels/{funnelId}/issues', methods=['GET']) def get_funnel_issues(projectId, funnelId, context): params = app.current_request.query_params if params is None: params = {} return funnels.get_issues(funnel_id=funnelId, project_id=projectId, range_value=params.get("range_value", None), start_date=params.get('startDate', None), end_date=params.get('endDate', None)) @app.route('/{projectId}/funnels/{funnelId}/issues', methods=['POST', 'PUT']) def get_funnel_issues_on_the_fly(projectId, funnelId, context): params = app.current_request.query_params if params is None: params = {} data = app.current_request.json_body if data is None: data = {} return {"data": funnels.get_issues_on_the_fly(funnel_id=funnelId, project_id=projectId, data={**params, **data})} @app.route('/{projectId}/funnels/{funnelId}/sessions', methods=['GET']) def get_funnel_sessions(projectId, funnelId, context): params = app.current_request.query_params if params is None: params = {} return {"data": funnels.get_sessions(funnel_id=funnelId, user_id=context['userId'], project_id=projectId, range_value=params.get("range_value", None), start_date=params.get('startDate', None), end_date=params.get('endDate', None))} @app.route('/{projectId}/funnels/{funnelId}/sessions', methods=['POST', 'PUT']) def get_funnel_sessions_on_the_fly(projectId, funnelId, context): params = app.current_request.query_params if params is None: params = {} data = app.current_request.json_body if data is None: data = {} return {"data": funnels.get_sessions_on_the_fly(funnel_id=funnelId, user_id=context['userId'], project_id=projectId, data={**params, **data})} @app.route('/{projectId}/funnels/issues/{issueId}/sessions', methods=['GET']) def get_issue_sessions(projectId, issueId, context): params = app.current_request.query_params if params is None: params = {} issue = issues.get(project_id=projectId, issue_id=issueId) return { "data": {"sessions": sessions.search_by_issue(user_id=context["userId"], project_id=projectId, issue=issue, start_date=params.get('startDate', None), end_date=params.get('endDate', None)), "issue": issue}} @app.route('/{projectId}/funnels/{funnelId}/issues/{issueId}/sessions', methods=['POST', 'PUT']) def get_funnel_issue_sessions(projectId, funnelId, issueId, context): data = app.current_request.json_body data = funnels.search_by_issue(project_id=projectId, user_id=context["userId"], issue_id=issueId, funnel_id=funnelId, data=data) if "errors" in data: return data if data.get("issue") is None: data["issue"] = issues.get(project_id=projectId, issue_id=issueId) return { "data": data } @app.route('/{projectId}/funnels/{funnelId}', methods=['GET']) def get_funnel(projectId, funnelId, context): data = funnels.get(funnel_id=funnelId, project_id=projectId) if data is None: return {"errors": ["funnel not found"]} return data @app.route('/{projectId}/funnels/{funnelId}', methods=['POST', 'PUT']) def edit_funnel(projectId, funnelId, context): data = app.current_request.json_body return funnels.update(funnel_id=funnelId, user_id=context['userId'], name=data.get("name"), filter=data.get("filter"), is_public=data.get("isPublic")) @app.route('/{projectId}/funnels/{funnelId}', methods=['DELETE']) def delete_filter(projectId, funnelId, context): return funnels.delete(user_id=context['userId'], funnel_id=funnelId, project_id=projectId) @app.route('/{projectId}/sourcemaps', methods=['PUT'], authorizer=bp_authorizers.api_key_authorizer) def sign_sourcemap_for_upload(projectId, context): data = app.current_request.json_body project_id = projects.get_internal_project_id(projectId) if project_id is None: return Response(status_code=400, body='invalid projectId') return {"data": sourcemaps.presign_upload_urls(project_id=project_id, urls=data["URL"])} @app.route('/config/weekly_report', methods=['GET']) def get_weekly_report_config(context): return {"data": weekly_report.get_config(user_id=context['userId'])} @app.route('/config/weekly_report', methods=['POST', 'PUT']) def get_weekly_report_config(context): data = app.current_request.json_body return {"data": weekly_report.edit_config(user_id=context['userId'], weekly_report=data.get("weeklyReport", True))} @app.route('/{projectId}/issue_types', methods=['GET']) def issue_types(projectId, context): # return {"data": issues.get_types_by_project(project_id=projectId)} return {"data": issues.get_all_types()} @app.route('/issue_types', methods=['GET']) def all_issue_types(context): return {"data": issues.get_all_types()} @app.route('/flows', methods=['GET', 'PUT', 'POST', 'DELETE']) @app.route('/{projectId}/flows', methods=['GET', 'PUT', 'POST', 'DELETE']) def removed_endpoints(projectId=None, context=None): return Response(body={"errors": ["Endpoint no longer available"]}, status_code=410) @app.route('/{projectId}/assist/sessions', methods=['GET']) def sessions_live(projectId, context): data = assist.get_live_sessions(projectId) return {'data': data} @app.route('/{projectId}/assist/sessions', methods=['POST']) def sessions_live_search(projectId, context): data = app.current_request.json_body if data is None: data = {} data = assist.get_live_sessions(projectId, filters=data.get("filters")) return {'data': data} @app.route('/{projectId}/heatmaps/url', methods=['POST']) def get_heatmaps_by_url(projectId, context): data = app.current_request.json_body return {"data": heatmaps.get_by_url(project_id=projectId, data=data)}