change(api): assist stats api moved to ee (#1598)

This commit is contained in:
Shekar Siri 2023-10-31 15:29:36 +01:00 committed by GitHub
parent bd2bcd378b
commit 325d893db5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 149 additions and 140 deletions

View file

@ -3,7 +3,6 @@ from apscheduler.triggers.interval import IntervalTrigger
from chalicelib.core import telemetry
from chalicelib.core import weekly_report, jobs, health
from chalicelib.core import assist_stats
async def run_scheduled_jobs() -> None:
@ -26,10 +25,6 @@ async def weekly_health_cron() -> None:
health.weekly_cron()
async def assist_events_aggregates_cron() -> None:
assist_stats.insert_aggregated_data()
cron_jobs = [
{"func": telemetry_cron, "trigger": CronTrigger(day_of_week="*"),
"misfire_grace_time": 60 * 60, "max_instances": 1},
@ -40,7 +35,5 @@ cron_jobs = [
{"func": health_cron, "trigger": IntervalTrigger(hours=0, minutes=30, start_date="2023-04-01 0:0:0", jitter=300),
"misfire_grace_time": 60 * 60, "max_instances": 1},
{"func": weekly_health_cron, "trigger": CronTrigger(day_of_week="sun", hour=5),
"misfire_grace_time": 60 * 60, "max_instances": 1},
{"func": assist_events_aggregates_cron,
"trigger": IntervalTrigger(hours=1, start_date="2023-04-01 0:0:0", jitter=10), }
"misfire_grace_time": 60 * 60, "max_instances": 1}
]

View file

@ -10,7 +10,7 @@ from chalicelib.core import log_tool_rollbar, sourcemaps, events, sessions_assig
log_tool_stackdriver, reset_password, log_tool_cloudwatch, log_tool_sentry, log_tool_sumologic, log_tools, sessions, \
log_tool_newrelic, announcements, log_tool_bugsnag, weekly_report, integration_jira_cloud, integration_github, \
assist, mobile, tenants, boarding, notifications, webhook, users, \
custom_metrics, saved_search, integrations_global, assist_stats
custom_metrics, saved_search, integrations_global
from chalicelib.core.collaboration_msteams import MSTeams
from chalicelib.core.collaboration_slack import Slack
from or_dependencies import OR_context, OR_role
@ -860,59 +860,3 @@ async def check_recording_status(project_id: int):
def health_check():
return {}
@public_app.get('/{project_id}/assist-stats/avg', tags=["assist-stats"])
def get_assist_stats_avg(
project_id: int,
startTimestamp: int = None,
endTimestamp: int = None,
userId: str = None
):
return assist_stats.get_averages(
project_id=project_id,
start_timestamp=startTimestamp,
end_timestamp=endTimestamp,
user_id=userId)
@public_app.get(
'/{project_id}/assist-stats/top-members',
tags=["assist-stats"],
response_model=schemas.AssistStatsTopMembersResponse
)
def get_assist_stats_top_members(
project_id: int,
startTimestamp: int = None,
endTimestamp: int = None,
sort: Optional[str] = Query(default="sessionsAssisted",
description="Sort options: " + ", ".join(assist_stats.event_type_mapping)),
order: str = "desc",
userId: int = None,
page: int = 0,
limit: int = 5
):
return assist_stats.get_top_members(
project_id=project_id,
start_timestamp=startTimestamp,
end_timestamp=endTimestamp,
sort_by=sort,
sort_order=order,
user_id=userId,
page=page,
limit=limit
)
@public_app.post(
'/{project_id}/assist-stats/sessions',
tags=["assist-stats"],
response_model=schemas.AssistStatsSessionsResponse
)
def get_assist_stats_sessions(
project_id: int,
data: schemas.AssistStatsSessionsRequest = Body(...),
):
return assist_stats.get_sessions(
project_id=project_id,
data=data
)

View file

@ -1581,75 +1581,3 @@ class ModuleStatus(BaseModel):
"offline-recordings", "alerts"] = Field(..., description="Possible values: notes, bugs, live")
status: bool = Field(...)
class AssistStatsAverage(BaseModel):
key: str = Field(...)
avg: float = Field(...)
chartData: List[dict] = Field(...)
class AssistStatsMember(BaseModel):
name: str
count: int
assist_duration: Optional[int] = Field(default=0)
call_duration: Optional[int] = Field(default=0)
control_duration: Optional[int] = Field(default=0)
assist_count: Optional[int] = Field(default=0)
class AssistStatsSessionAgent(BaseModel):
name: str
id: int
class AssistStatsTopMembersResponse(BaseModel):
total: int
list: List[AssistStatsMember]
class AssistStatsSessionRecording(BaseModel):
recordId: int = Field(...)
name: str = Field(...)
duration: int = Field(...)
class AssistStatsSession(BaseModel):
sessionId: str = Field(...)
timestamp: int = Field(...)
teamMembers: List[AssistStatsSessionAgent] = Field(...)
assistDuration: Optional[int] = Field(default=0)
callDuration: Optional[int] = Field(default=0)
controlDuration: Optional[int] = Field(default=0)
# recordings: list[AssistStatsSessionRecording] = Field(default=[])
assist_sort_options = ["timestamp", "assist_duration", "call_duration", "control_duration"]
class AssistStatsSessionsRequest(BaseModel):
startTimestamp: int = Field(...)
endTimestamp: int = Field(...)
limit: Optional[int] = Field(default=10)
page: Optional[int] = Field(default=1)
sort: Optional[str] = Field(default="timestamp",
enum=assist_sort_options)
order: Optional[str] = Field(default="desc", choices=["desc", "asc"])
userId: Optional[int] = Field(default=None)
@field_validator("sort")
def validate_sort(cls, v):
if v not in assist_sort_options:
raise ValueError(f"Invalid sort option. Allowed options: {', '.join(assist_sort_options)}")
return v
@field_validator("order")
def validate_order(cls, v):
if v not in ["desc", "asc"]:
raise ValueError("Invalid order option. Must be 'desc' or 'asc'.")
return v
class AssistStatsSessionsResponse(BaseModel):
total: int = Field(...)
page: int = Field(...)
list: List[AssistStatsSession] = Field(default=[])

1
ee/api/.gitignore vendored
View file

@ -251,7 +251,6 @@ Pipfile.lock
/routers/subs/__init__.py
/routers/__init__.py
/chalicelib/core/assist.py
/chalicelib/core/assist_stats.py
/auth/__init__.py
/auth/auth_apikey.py
/build.sh

View file

@ -73,7 +73,6 @@ rm -rf ./crons/__init__.py
rm -rf ./routers/subs/__init__.py
rm -rf ./routers/__init__.py
rm -rf ./chalicelib/core/assist.py
rm -rf ./chalicelib/core/assist_stats.py
rm -rf ./auth/__init__.py
rm -rf ./auth/auth_apikey.py
rm -rf ./build.sh

View file

@ -1,12 +1,19 @@
from apscheduler.triggers.interval import IntervalTrigger
from chalicelib.utils import events_queue
from chalicelib.core import assist_stats
async def pg_events_queue() -> None:
events_queue.global_queue.force_flush()
async def assist_events_aggregates_cron() -> None:
assist_stats.insert_aggregated_data()
ee_cron_jobs = [
{"func": pg_events_queue, "trigger": IntervalTrigger(minutes=5), "misfire_grace_time": 20, "max_instances": 1},
{"func": assist_events_aggregates_cron,
"trigger": IntervalTrigger(hours=1, start_date="2023-04-01 0:0:0", jitter=10), }
]

View file

@ -1,6 +1,6 @@
from chalicelib.core import roles, traces, assist_records, sessions
from chalicelib.core import unlock, signals
from chalicelib.core import sessions_insights
from chalicelib.core import sessions_insights, assist_stats
from chalicelib.utils import assist_helper
unlock.check()
@ -135,3 +135,60 @@ def send_interactions(projectId: int, data: schemas.SignalsSchema = Body(...),
def sessions_search(projectId: int, data: schemas.GetInsightsSchema = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
return {'data': sessions_insights.fetch_selected(data=data, project_id=projectId)}
@public_app.get('/{project_id}/assist-stats/avg', tags=["assist-stats"])
def get_assist_stats_avg(
project_id: int,
startTimestamp: int = None,
endTimestamp: int = None,
userId: str = None
):
return assist_stats.get_averages(
project_id=project_id,
start_timestamp=startTimestamp,
end_timestamp=endTimestamp,
user_id=userId)
@public_app.get(
'/{project_id}/assist-stats/top-members',
tags=["assist-stats"],
response_model=schemas.AssistStatsTopMembersResponse
)
def get_assist_stats_top_members(
project_id: int,
startTimestamp: int = None,
endTimestamp: int = None,
sort: Optional[str] = Query(default="sessionsAssisted",
description="Sort options: " + ", ".join(assist_stats.event_type_mapping)),
order: str = "desc",
userId: int = None,
page: int = 0,
limit: int = 5
):
return assist_stats.get_top_members(
project_id=project_id,
start_timestamp=startTimestamp,
end_timestamp=endTimestamp,
sort_by=sort,
sort_order=order,
user_id=userId,
page=page,
limit=limit
)
@public_app.post(
'/{project_id}/assist-stats/sessions',
tags=["assist-stats"],
response_model=schemas.AssistStatsSessionsResponse
)
def get_assist_stats_sessions(
project_id: int,
data: schemas.AssistStatsSessionsRequest = Body(...),
):
return assist_stats.get_sessions(
project_id=project_id,
data=data
)

View file

@ -1,3 +1,4 @@
from .schemas import *
from .schemas_ee import *
from .assist_stats_schema import *
from . import overrides as _overrides

View file

@ -0,0 +1,78 @@
from typing import Optional, List
from pydantic import Field, field_validator
from .overrides import BaseModel, Enum, ORUnion
class AssistStatsAverage(BaseModel):
key: str = Field(...)
avg: float = Field(...)
chartData: List[dict] = Field(...)
class AssistStatsMember(BaseModel):
name: str
count: int
assist_duration: Optional[int] = Field(default=0)
call_duration: Optional[int] = Field(default=0)
control_duration: Optional[int] = Field(default=0)
assist_count: Optional[int] = Field(default=0)
class AssistStatsSessionAgent(BaseModel):
name: str
id: int
class AssistStatsTopMembersResponse(BaseModel):
total: int
list: List[AssistStatsMember]
class AssistStatsSessionRecording(BaseModel):
recordId: int = Field(...)
name: str = Field(...)
duration: int = Field(...)
class AssistStatsSession(BaseModel):
sessionId: str = Field(...)
timestamp: int = Field(...)
teamMembers: List[AssistStatsSessionAgent] = Field(...)
assistDuration: Optional[int] = Field(default=0)
callDuration: Optional[int] = Field(default=0)
controlDuration: Optional[int] = Field(default=0)
# recordings: list[AssistStatsSessionRecording] = Field(default=[])
assist_sort_options = ["timestamp", "assist_duration", "call_duration", "control_duration"]
class AssistStatsSessionsRequest(BaseModel):
startTimestamp: int = Field(...)
endTimestamp: int = Field(...)
limit: Optional[int] = Field(default=10)
page: Optional[int] = Field(default=1)
sort: Optional[str] = Field(default="timestamp",
enum=assist_sort_options)
order: Optional[str] = Field(default="desc", choices=["desc", "asc"])
userId: Optional[int] = Field(default=None)
@field_validator("sort")
def validate_sort(cls, v):
if v not in assist_sort_options:
raise ValueError(f"Invalid sort option. Allowed options: {', '.join(assist_sort_options)}")
return v
@field_validator("order")
def validate_order(cls, v):
if v not in ["desc", "asc"]:
raise ValueError("Invalid order option. Must be 'desc' or 'asc'.")
return v
class AssistStatsSessionsResponse(BaseModel):
total: int = Field(...)
page: int = Field(...)
list: List[AssistStatsSession] = Field(default=[])

View file

@ -156,3 +156,6 @@ class CardInsights(schemas.CardInsights):
CardSchema = ORUnion(Union[schemas.__cards_union_base, CardInsights], discriminator='metric_type')