parent
4df268c8ac
commit
0b6d2442a8
|
|
@ -39,6 +39,6 @@ api_router.include_router(clinicDoctor.router, prefix="/clinic-doctors", tags=["
|
|||
|
||||
api_router.include_router(dashboard.router, prefix="/dashboard", tags=["dashboard"], dependencies=[Depends(auth_required)])
|
||||
|
||||
api_router.include_router(call_transcripts.router, prefix="/call-transcripts", tags=["call-transcripts"], dependencies=[Depends(auth_required)])
|
||||
api_router.include_router(call_transcripts.router, prefix="/call-transcripts", tags=["call-transcripts"])
|
||||
|
||||
api_router.include_router(notifications.router, prefix="/notifications", tags=["notifications"], dependencies=[Depends(auth_required)])
|
||||
|
|
|
|||
|
|
@ -60,8 +60,15 @@ async def update_master_data(master_appointment_type_id: int, appointment_type:
|
|||
|
||||
|
||||
@router.get("/master-data")
|
||||
async def get_master_data():
|
||||
appointment_types = await MasterAppointmentServices().get_master_appointment_types()
|
||||
async def get_master_data(
|
||||
limit: int = DEFAULT_LIMIT,
|
||||
page: int = DEFAULT_PAGE,
|
||||
search: str = ""
|
||||
):
|
||||
if page < 1:
|
||||
page = 1
|
||||
offset = (page - 1) * limit
|
||||
appointment_types = await MasterAppointmentServices().get_master_appointment_types(limit, offset, search)
|
||||
return ApiResponse(data=appointment_types, message="Master data retrieved successfully")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,42 @@
|
|||
from fastapi import APIRouter, BackgroundTasks
|
||||
import datetime
|
||||
from typing import Optional
|
||||
from fastapi import APIRouter, BackgroundTasks, Depends
|
||||
from services.callTranscripts import CallTranscriptServices
|
||||
from utils.constants import DEFAULT_LIMIT, DEFAULT_PAGE
|
||||
from middleware.auth_dependency import auth_required
|
||||
from utils.constants import DEFAULT_LIMIT, DEFAULT_ORDER, DEFAULT_ORDER_BY, DEFAULT_PAGE
|
||||
from schemas.ApiResponse import ApiResponse
|
||||
from schemas.CreateSchemas import CallTranscriptsCreate
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def get_call_transcripts(limit:int = DEFAULT_LIMIT, page:int = DEFAULT_PAGE):
|
||||
@router.get("/", dependencies=[Depends(auth_required)])
|
||||
async def get_call_transcripts(limit: int = DEFAULT_LIMIT, page: int = DEFAULT_PAGE, search: str = "", orderBy: str = DEFAULT_ORDER, order: str = DEFAULT_ORDER_BY, startDate: Optional[datetime.datetime] = None, endDate: Optional[datetime.datetime] = None):
|
||||
if page == 0:
|
||||
page = 1
|
||||
offset = (page - 1) * limit
|
||||
response = await CallTranscriptServices().get_call_transcripts(limit, offset)
|
||||
response = await CallTranscriptServices().get_call_transcripts(limit, offset, search, orderBy, order, startDate, endDate)
|
||||
return ApiResponse(data=response, message="Call transcripts retrieved successfully")
|
||||
|
||||
@router.post("/bulk-download")
|
||||
async def bulk_download_call_transcripts(key_ids: list[int], background_tasks: BackgroundTasks):
|
||||
|
||||
@router.get("/{key_id}", dependencies=[Depends(auth_required)])
|
||||
async def download_call_transcript(key_id: str):
|
||||
service = CallTranscriptServices()
|
||||
response = await service.download_call_transcript(key_id)
|
||||
return ApiResponse(data=response, message="Call transcript downloaded successfully")
|
||||
|
||||
|
||||
@router.post("/")
|
||||
async def create_call_transcript(data: CallTranscriptsCreate):
|
||||
service = CallTranscriptServices()
|
||||
await service.create_call_transcript(data)
|
||||
return ApiResponse(data="OK", message="Call transcript created successfully")
|
||||
|
||||
|
||||
@router.post("/bulk-download", dependencies=[Depends(auth_required)])
|
||||
async def bulk_download_call_transcripts(
|
||||
key_ids: list[int], background_tasks: BackgroundTasks
|
||||
):
|
||||
service = CallTranscriptServices()
|
||||
response = await service.bulk_download_call_transcripts(key_ids, background_tasks)
|
||||
return response
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from sqlalchemy import Column, Integer, String
|
||||
from sqlalchemy import Column, Integer, String, DateTime
|
||||
|
||||
|
||||
from database import Base
|
||||
|
|
@ -9,9 +9,10 @@ class CallTranscripts(Base, CustomBase):
|
|||
__tablename__ = "call_transcripts"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
patient_name = Column(String)
|
||||
patient_name = Column(String, nullable=True)
|
||||
patient_number = Column(String)
|
||||
call_duration = Column(String)
|
||||
call_received_time = Column(String)
|
||||
call_received_time = Column(DateTime(timezone=True))
|
||||
transcript_key_id = Column(String)
|
||||
clinic_id = Column(Integer, nullable=True, default=None)
|
||||
|
||||
|
|
@ -119,10 +119,10 @@ class ClinicDoctorBase(BaseModel):
|
|||
|
||||
|
||||
class CallTranscriptsBase(BaseModel):
|
||||
patient_name:str
|
||||
patient_name:Optional[str] = None
|
||||
patient_number:str
|
||||
call_duration:str
|
||||
call_received_time:str
|
||||
call_received_time:datetime
|
||||
transcript_key_id:str
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ class AuthService:
|
|||
self.db.add(reset_password)
|
||||
self.db.commit()
|
||||
|
||||
reset_password_url = f"{self.url}/auth/reset-password?token={reset_password_token}"
|
||||
reset_password_url = f"{self.url}auth/reset-password?token={reset_password_token}"
|
||||
|
||||
self.email_service.send_reset_password_email(email, reset_password_url)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import datetime
|
||||
from typing import Optional
|
||||
from fastapi import BackgroundTasks
|
||||
from sqlalchemy.orm import Session
|
||||
import tempfile
|
||||
|
|
@ -6,7 +8,7 @@ import time
|
|||
from fastapi.responses import FileResponse
|
||||
import os
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
from sqlalchemy import desc
|
||||
from schemas.ResponseSchemas import CallTranscriptsResponse
|
||||
from database import get_db
|
||||
from models.CallTranscripts import CallTranscripts
|
||||
|
|
@ -15,23 +17,44 @@ from services.s3Service import get_signed_url
|
|||
from interface.common_response import CommonResponse
|
||||
from loguru import logger
|
||||
|
||||
from schemas.CreateSchemas import CallTranscriptsCreate
|
||||
|
||||
from exceptions.db_exceptions import DBExceptionHandler
|
||||
|
||||
class CallTranscriptServices:
|
||||
def __init__(self):
|
||||
self.db:Session = next(get_db())
|
||||
self.logger = logger
|
||||
|
||||
async def get_call_transcripts(self, limit:int, offset:int):
|
||||
|
||||
async def create_call_transcript(self, data:CallTranscriptsCreate):
|
||||
try:
|
||||
call_transcripts = self.db.query(CallTranscripts).limit(limit).offset(offset).all()
|
||||
call_transcript = CallTranscripts(**data.model_dump())
|
||||
self.db.add(call_transcript)
|
||||
self.db.commit()
|
||||
return
|
||||
except Exception as e:
|
||||
DBExceptionHandler.handle_exception(e, context="creating call transcript")
|
||||
finally:
|
||||
self.db.close()
|
||||
|
||||
async def get_call_transcripts(self, limit:int, offset:int, search: str = "", orderBy: str = "call_received_time", order: str = "ASC", startDate: Optional[datetime.datetime] = None, endDate: Optional[datetime.datetime] = None):
|
||||
try:
|
||||
query = self.db.query(CallTranscripts).order_by(desc(getattr(CallTranscripts, orderBy)) if order == "DESC" else getattr(CallTranscripts, orderBy))
|
||||
|
||||
if search:
|
||||
query = query.filter(CallTranscripts.patient_number.contains(search))
|
||||
|
||||
if startDate and endDate:
|
||||
query = query.filter(CallTranscripts.call_received_time.between(startDate, endDate))
|
||||
|
||||
call_transcripts = query.limit(limit).offset(offset).all()
|
||||
|
||||
total = self.db.query(CallTranscripts).count()
|
||||
|
||||
response = [CallTranscriptsResponse(**call_transcript.__dict__.copy()) for call_transcript in call_transcripts]
|
||||
|
||||
for call_transcript in response:
|
||||
call_transcript.transcript_key_id = get_signed_url(call_transcript.transcript_key_id)
|
||||
call_transcript.transcript_key_id = await get_signed_url(call_transcript.transcript_key_id)
|
||||
|
||||
return_response = CommonResponse(data=response, total=total)
|
||||
|
||||
|
|
@ -41,7 +64,7 @@ class CallTranscriptServices:
|
|||
finally:
|
||||
self.db.close()
|
||||
|
||||
def download_call_transcript(self, key_id: str):
|
||||
async def download_call_transcript(self, key_id: str):
|
||||
try:
|
||||
call_transcript = self.db.query(CallTranscripts).filter(CallTranscripts.transcript_key_id == key_id).first()
|
||||
|
||||
|
|
@ -115,7 +138,7 @@ class CallTranscriptServices:
|
|||
download_info = []
|
||||
for key in keys:
|
||||
# Generate signed URL for each key
|
||||
url = get_signed_url(key)
|
||||
url = await get_signed_url(key)
|
||||
|
||||
# Determine filename (using key's basename or a formatted name)
|
||||
filename = os.path.basename(key)
|
||||
|
|
@ -148,14 +171,14 @@ class CallTranscriptServices:
|
|||
zip_file.write(file_path, arcname=arcname)
|
||||
|
||||
# Add cleanup task to run after response is sent
|
||||
background_tasks.add_task(self.cleanup_temp_files, temp_dir, zip_path)
|
||||
# background_tasks.add_task(self.cleanup_temp_files, temp_dir, zip_path)
|
||||
|
||||
# Return the zip file as a response
|
||||
return FileResponse(
|
||||
path=zip_path,
|
||||
media_type="application/zip",
|
||||
filename="call_transcripts.zip",
|
||||
background=background_tasks
|
||||
# background=background_tasks
|
||||
)
|
||||
except Exception as e:
|
||||
DBExceptionHandler.handle_exception(e, context="bulk downloading call transcripts")
|
||||
|
|
|
|||
|
|
@ -14,10 +14,16 @@ class MasterAppointmentServices:
|
|||
self.logger = logger
|
||||
|
||||
|
||||
async def get_master_appointment_types(self):
|
||||
async def get_master_appointment_types(self, limit: int, offset: int, search: str):
|
||||
try:
|
||||
appointment_types = self.db.query(MasterAppointmentTypes).all()
|
||||
total= self.db.query(MasterAppointmentTypes).count()
|
||||
query = self.db.query(MasterAppointmentTypes)
|
||||
total= query.count()
|
||||
|
||||
if search:
|
||||
query = query.filter(MasterAppointmentTypes.type.contains(search))
|
||||
total = query.count()
|
||||
|
||||
appointment_types = query.limit(limit).offset(offset).all()
|
||||
response = CommonResponse(data=[MasterAppointmentTypeResponse(**appointment_type.__dict__.copy()) for appointment_type in appointment_types], total=total)
|
||||
return response
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -110,8 +110,9 @@ async def get_signed_url(key: str) -> str:
|
|||
Params={
|
||||
'Bucket': s3_service.bucket_name,
|
||||
'Key': key,
|
||||
'ResponseContentDisposition': 'attachment'
|
||||
},
|
||||
ExpiresIn=3600 # 1 hour
|
||||
ExpiresIn=3600, # 1 hour
|
||||
)
|
||||
return url
|
||||
except ClientError as e:
|
||||
|
|
|
|||
Loading…
Reference in New Issue