Ali2206 commited on
Commit
bd7030e
·
1 Parent(s): 0bd1eaa

device token

Browse files
Files changed (2) hide show
  1. api/routes/txagent.py +99 -0
  2. voice.py +15 -35
api/routes/txagent.py CHANGED
@@ -343,6 +343,66 @@ async def chat_with_txagent(
343
  logger.error(f"Error in TxAgent chat: {e}")
344
  raise HTTPException(status_code=500, detail="Failed to process chat request")
345
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  @router.post("/voice/transcribe")
347
  async def transcribe_audio(
348
  audio: UploadFile = File(...),
@@ -678,4 +738,43 @@ async def get_all_patients_analysis_reports_pdf(
678
  logger.error(f"Error generating PDF report for all patients: {str(e)}")
679
  raise HTTPException(status_code=500, detail=f"Failed to generate PDF report: {str(e)}")
680
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
681
 
 
343
  logger.error(f"Error in TxAgent chat: {e}")
344
  raise HTTPException(status_code=500, detail="Failed to process chat request")
345
 
346
+ @router.post("/chat-stream")
347
+ async def chat_stream_with_txagent(
348
+ request: ChatRequest,
349
+ current_user: dict = Depends(get_current_user)
350
+ ):
351
+ """Streaming chat avec TxAgent intégré"""
352
+ try:
353
+ # Vérifier que l'utilisateur est médecin ou admin
354
+ if not any(role in current_user.get('roles', []) for role in ['doctor', 'admin']):
355
+ raise HTTPException(status_code=403, detail="Only doctors and admins can use TxAgent")
356
+
357
+ logger.info(f"Chat stream initiated by {current_user['email']}: {request.message}")
358
+
359
+ # Generate a response (for now, a simple response)
360
+ response_text = f"Hello! I'm your clinical assistant. You said: '{request.message}'. How can I help you with patient care today?"
361
+
362
+ # Store the chat in the database
363
+ try:
364
+ from db.mongo import db
365
+ chats_collection = db.chats
366
+
367
+ chat_entry = {
368
+ "message": request.message,
369
+ "response": response_text,
370
+ "user_id": current_user.get('_id'),
371
+ "user_email": current_user.get('email'),
372
+ "timestamp": datetime.utcnow(),
373
+ "patient_id": request.patient_id if hasattr(request, 'patient_id') else None,
374
+ "chat_type": "text_chat"
375
+ }
376
+
377
+ await chats_collection.insert_one(chat_entry)
378
+ logger.info(f"Chat stored in database for user {current_user['email']}")
379
+
380
+ except Exception as db_error:
381
+ logger.error(f"Failed to store chat in database: {str(db_error)}")
382
+ # Continue even if database storage fails
383
+
384
+ # Return streaming response
385
+ async def generate_response():
386
+ # Simulate streaming by sending the response in chunks
387
+ words = response_text.split()
388
+ chunk_size = 3 # Send 3 words at a time
389
+
390
+ for i in range(0, len(words), chunk_size):
391
+ chunk = " ".join(words[i:i + chunk_size])
392
+ if i + chunk_size < len(words):
393
+ chunk += " " # Add space if not the last chunk
394
+ yield chunk
395
+ await asyncio.sleep(0.1) # Small delay to simulate streaming
396
+
397
+ return StreamingResponse(
398
+ generate_response(),
399
+ media_type="text/plain"
400
+ )
401
+
402
+ except Exception as e:
403
+ logger.error(f"Error in TxAgent chat stream: {e}")
404
+ raise HTTPException(status_code=500, detail="Failed to process chat stream request")
405
+
406
  @router.post("/voice/transcribe")
407
  async def transcribe_audio(
408
  audio: UploadFile = File(...),
 
738
  logger.error(f"Error generating PDF report for all patients: {str(e)}")
739
  raise HTTPException(status_code=500, detail=f"Failed to generate PDF report: {str(e)}")
740
 
741
+ # Voice synthesis endpoint
742
+ @router.post("/voice/synthesize")
743
+ async def synthesize_voice(
744
+ request: dict,
745
+ current_user: dict = Depends(get_current_user)
746
+ ):
747
+ """
748
+ Convert text to speech using gTTS
749
+ """
750
+ try:
751
+ logger.info(f"Voice synthesis initiated by {current_user['email']}")
752
+
753
+ # Extract parameters from request
754
+ text = request.get('text', '')
755
+ language = request.get('language', 'en-US')
756
+ return_format = request.get('return_format', 'mp3')
757
+
758
+ if not text:
759
+ raise HTTPException(status_code=400, detail="Text is required")
760
+
761
+ # Convert language code for gTTS (e.g., 'en-US' -> 'en')
762
+ language_code = language.split('-')[0] if '-' in language else language
763
+
764
+ # Generate speech
765
+ audio_data = text_to_speech(text, language=language_code)
766
+
767
+ # Return audio data
768
+ return StreamingResponse(
769
+ io.BytesIO(audio_data),
770
+ media_type=f"audio/{return_format}",
771
+ headers={"Content-Disposition": f"attachment; filename=speech.{return_format}"}
772
+ )
773
+
774
+ except HTTPException:
775
+ raise
776
+ except Exception as e:
777
+ logger.error(f"Error in voice synthesis: {e}")
778
+ raise HTTPException(status_code=500, detail="Error generating voice output")
779
+
780
 
voice.py CHANGED
@@ -1,32 +1,24 @@
1
  from typing import Optional
2
  from fastapi import HTTPException
3
- from config import logger
4
  import io
5
- import speech_recognition as sr
6
  from gtts import gTTS
7
- from pydub import AudioSegment
8
- import base64
9
- from utils import clean_text_response # Added this import
10
 
11
- def recognize_speech(audio_data: bytes, language: str = "en-US") -> str:
12
- recognizer = sr.Recognizer()
13
- try:
14
- with io.BytesIO(audio_data) as audio_file:
15
- with sr.AudioFile(audio_file) as source:
16
- audio = recognizer.record(source)
17
- text = recognizer.recognize_google(audio, language=language)
18
- return text
19
- except sr.UnknownValueError:
20
- logger.error("Google Speech Recognition could not understand audio")
21
- raise HTTPException(status_code=400, detail="Could not understand audio")
22
- except sr.RequestError as e:
23
- logger.error(f"Could not request results from Google Speech Recognition service; {e}")
24
- raise HTTPException(status_code=503, detail="Speech recognition service unavailable")
25
- except Exception as e:
26
- logger.error(f"Error in speech recognition: {e}")
27
- raise HTTPException(status_code=500, detail="Error processing speech")
28
 
29
  def text_to_speech(text: str, language: str = "en", slow: bool = False) -> bytes:
 
 
 
 
 
 
 
 
 
 
 
30
  try:
31
  tts = gTTS(text=text, lang=language, slow=slow)
32
  mp3_fp = io.BytesIO()
@@ -35,16 +27,4 @@ def text_to_speech(text: str, language: str = "en", slow: bool = False) -> bytes
35
  return mp3_fp.read()
36
  except Exception as e:
37
  logger.error(f"Error in text-to-speech conversion: {e}")
38
- raise HTTPException(status_code=500, detail="Error generating speech")
39
-
40
- def extract_text_from_pdf(pdf_data: bytes) -> str:
41
- try:
42
- from PyPDF2 import PdfReader
43
- pdf_reader = PdfReader(io.BytesIO(pdf_data))
44
- text = ""
45
- for page in pdf_reader.pages:
46
- text += page.extract_text() or ""
47
- return clean_text_response(text) # Now works with the import
48
- except Exception as e:
49
- logger.error(f"Error extracting text from PDF: {e}")
50
- raise HTTPException(status_code=400, detail="Failed to extract text from PDF")
 
1
  from typing import Optional
2
  from fastapi import HTTPException
3
+ import logging
4
  import io
 
5
  from gtts import gTTS
 
 
 
6
 
7
+ # Configure logging
8
+ logger = logging.getLogger(__name__)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  def text_to_speech(text: str, language: str = "en", slow: bool = False) -> bytes:
11
+ """
12
+ Convert text to speech using gTTS (Google Text-to-Speech)
13
+
14
+ Args:
15
+ text (str): The text to convert to speech
16
+ language (str): Language code (default: "en")
17
+ slow (bool): Whether to speak slowly (default: False)
18
+
19
+ Returns:
20
+ bytes: MP3 audio data
21
+ """
22
  try:
23
  tts = gTTS(text=text, lang=language, slow=slow)
24
  mp3_fp = io.BytesIO()
 
27
  return mp3_fp.read()
28
  except Exception as e:
29
  logger.error(f"Error in text-to-speech conversion: {e}")
30
+ raise HTTPException(status_code=500, detail="Error generating speech")