feat(api): service assist stats - udpated event structure
This commit is contained in:
parent
a9c2aa4c92
commit
4c237d5188
1 changed files with 73 additions and 71 deletions
|
|
@ -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
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue