feat(api): service assist stats - udpated event structure

This commit is contained in:
Shekar Siri 2023-10-03 13:15:50 +02:00
parent a9c2aa4c92
commit 4c237d5188

View file

@ -1,10 +1,8 @@
import logging import logging
from typing import Optional from fastapi import FastAPI, HTTPException, Depends
from fastapi import FastAPI, HTTPException, Depends, Response from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy import Column, Integer, String, DateTime, update, create_engine, PrimaryKeyConstraint, UniqueConstraint
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from datetime import datetime
from decouple import config from decouple import config
from enum import Enum as PythonEnum from enum import Enum as PythonEnum
from sqlalchemy import Enum from sqlalchemy import Enum
@ -52,53 +50,6 @@ def shutdown_db_client():
engine.dispose() engine.dispose()
class EventStateEnum(PythonEnum):
start = "start"
end = "end"
class EventTypeEnum(PythonEnum):
# live = "live"
assist = "assist"
call = "call"
remote = "remote"
record = "record"
class Event(Base):
__tablename__ = "assist_events"
project_id = Column(Integer, nullable=False)
session_id = Column(String, index=True)
event_type = Column(Enum(EventTypeEnum), nullable=False)
event_state = Column(Enum(EventStateEnum), nullable=False)
timestamp = Column(Integer, nullable=True)
user_id = Column(String, nullable=True)
agent_id = Column(String, nullable=True)
__table_args__ = (
PrimaryKeyConstraint('session_id', 'project_id', 'event_type', 'timestamp', name='pk_session_user_event'),
CheckConstraint(
event_type.in_(['live', 'assist', 'call', 'remote', 'record']),
name='event_type_check'
),
CheckConstraint(
event_state.in_(['start', 'end']),
name='event_state_check'
),
)
class EventCreate(BaseModel):
project_id: str = Field(..., description="The ID of the project")
session_id: str = Field(..., description="The session ID of the event")
event_type: EventTypeEnum = Field(..., description="The type of event")
event_state: EventStateEnum = Field(..., description="The state of the event")
user_id: Optional[str] = Field(None, description="The ID of the user")
agent_id: str = Field(..., description="The ID of the agent")
timestamp: int = Field(..., description="The timestamp of the event")
def get_db(): def get_db():
db = SessionLocal() db = SessionLocal()
try: try:
@ -107,14 +58,72 @@ def get_db():
db.close() db.close()
@app.post("/events", response_model=EventCreate) class EventStateEnum(PythonEnum):
async def create_event_start(event: EventCreate, db: Session = Depends(get_db)): start = "start"
end = "end"
class EventTypeEnum(PythonEnum):
assist = "assist"
call = "call"
control = "control"
record = "record"
class Event(Base):
__tablename__ = "assist_events"
event_id = Column(String, primary_key=True)
project_id = Column(Integer, nullable=False)
session_id = Column(String, index=True)
agent_id = Column(String, nullable=True)
event_type = Column(Enum(EventTypeEnum), nullable=False)
timestamp = Column(Integer, nullable=True)
duration = Column(Integer, nullable=True)
__table_args__ = (
CheckConstraint(
event_type.in_(['assist', 'call', 'control', 'record']),
name='event_type_check'
),
)
class EventCreate(BaseModel):
event_id: str = Field(..., description="The ID of the event")
project_id: int = Field(..., description="The ID of the project")
session_id: str = Field(..., description="The session ID of the event")
event_type: EventTypeEnum = Field(..., description="The type of event")
event_state: EventStateEnum = Field(..., description="The state of the event")
agent_id: str = Field(..., description="The ID of the agent")
timestamp: int = Field(..., description="The timestamp of the event")
def update_duration(event_id, timestamp, db):
try:
existing_event = db.query(Event).filter(Event.event_id == event_id).first()
if existing_event:
duration = timestamp - existing_event.timestamp
if duration < 0:
raise HTTPException(status_code=400, detail="Invalid timestamp")
existing_event.duration = duration
db.commit()
else:
raise HTTPException(status_code=400, detail="Existing event not found")
except Exception as e:
logging.error(f"Error updating duration -: {e}")
raise HTTPException(status_code=500, detail=str(e))
finally:
db.close()
def insert_event(event: EventCreate, db: Session):
db_event = Event( db_event = Event(
event_id=event.event_id,
session_id=event.session_id, session_id=event.session_id,
user_uuid=event.user_uuid, project_id=event.project_id,
event_type=event.event_type, event_type=event.event_type,
event_state=event.event_state,
user_id=event.user_id,
agent_id=event.agent_id, agent_id=event.agent_id,
timestamp=event.timestamp, timestamp=event.timestamp,
) )
@ -123,7 +132,6 @@ async def create_event_start(event: EventCreate, db: Session = Depends(get_db)):
db.add(db_event) db.add(db_event)
db.commit() db.commit()
db.refresh(db_event) db.refresh(db_event)
return Response(status_code=200)
except SQLAlchemyError as e: except SQLAlchemyError as e:
logging.error(f"Error creating event -: {e}") logging.error(f"Error creating event -: {e}")
@ -135,19 +143,13 @@ async def create_event_start(event: EventCreate, db: Session = Depends(get_db)):
except Exception as e: except Exception as e:
logging.error(f"Error creating event: {e}") logging.error(f"Error creating event: {e}")
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
finally:
db.close()
async def calculate_total_event_duration(event_type: EventTypeEnum, db: Session = Depends(get_db)): @app.post("/events")
events = db.query(Event).filter(Event.event_type == event_type).order_by(Event.timestamp).all() def create_event(event: EventCreate, db: Session = Depends(get_db)):
if event.event_state == EventStateEnum.end:
total_duration = 0 update_duration(event.event_id, event.timestamp, db)
start_time = None else:
insert_event(event, db)
for event in events:
if event.event_state == EventStateEnum.start:
start_time = event.timestamp
elif event.event_state == EventStateEnum.end and start_time is not None:
total_duration += event.timestamp - start_time
start_time = None
return total_duration