change /chat endpoint to return a url

parent b0bf570e
......@@ -148,32 +148,17 @@ def create_app() -> FastAPI:
"""Fetches the agent's text and audio response with proper CORS headers."""
try:
print("Getting audio response...")
result = container.response_service.get_agent_response(student_id=student_id)
if hasattr(result, 'status_code'):
# This is already a Response object from response_service
print(f"Response headers: {dict(result.headers)}")
print(f"Response audio raw bytes size: {len(result.body) if result.body else 'N/A'}")
print(f"Response audio first 20 bytes: {result.body[:20] if result.body else 'N/A'}")
return result
else:
# If it's not a Response object, create one
print("Creating new response object")
response_text = result.get('text', 'No response available')
# Encode the response text in base64 for the header
encoded_text = base64.b64encode(response_text.encode('utf-8')).decode('utf-8')
# Create response with proper headers
response = Response(
content=result.get('audio', b''),
media_type="audio/mpeg",
headers={
"X-Response-Text": encoded_text,
"Access-Control-Expose-Headers": "X-Response-Text",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "*"
}
)
print(f"Created response with headers: {dict(response.headers)}")
return response
......
......@@ -44,3 +44,16 @@ class MinIOStorageRepository(StorageRepository):
return "connected"
except Exception as e:
return f"error: {str(e)}"
def get_file_url(self, bucket: str, file_path: str, expires: int = 3600) -> str:
"""Generate a presigned URL to share an S3 object"""
try:
url = self.client.generate_presigned_url(
'get_object',
Params={'Bucket': bucket, 'Key': file_path},
ExpiresIn=expires
)
return url
except ClientError as e:
print(f"Error generating presigned URL: {e}")
return None
\ No newline at end of file
......@@ -60,7 +60,7 @@ class ChatService:
self.response_manager.store_response(
student_id = student_id,
text=agent_response_text,
audio_filename=audio_data.get("filename"),
audio_filepath=audio_data.get("filepath"),
audio_bytes=audio_data.get("bytes")
)
......@@ -71,7 +71,7 @@ class ChatService:
"message": "Message processed and agent response ready",
"student_id": student_id,
"agent_response": agent_response_text,
"audio_filename": audio_data.get("filename")
"audio_filepath": audio_data.get("filepath")
}
except Exception as e:
......@@ -93,11 +93,11 @@ class ChatService:
# 3. Determine filename and upload (same as before)
provider = os.getenv("TTS_PROVIDER", "openai").lower()
file_extension = "wav" if provider == "custom" else "mp3"
content_type = "audio/wav" if provider == "custom" else "audio/mpeg"
file_extension = "wav"
content_type = "audio/wav"
timestamp = int(time.time())
filename = f"agent_response_{timestamp}.{file_extension}"
filename = f"agent_response_{timestamp}_{student_id}.{file_extension}"
minio_file_path = f"audio/{filename}"
self.storage_repo.upload_file(
......@@ -106,9 +106,14 @@ class ChatService:
file_path=minio_file_path
)
full_url = self.storage_repo.get_file_url(
bucket=self.config.minio_bucket,
file_path=minio_file_path,
expires=3600 # 1 hour
)
print(f"Successfully generated and uploaded stitched TTS audio: {filename}")
return {"bytes": audio_bytes, "filename": filename}
return {"bytes": audio_bytes, "filepath": full_url}
except Exception as e:
print(f"Error in _generate_and_upload_audio: {e}")
return {"bytes": None, "filename": None}
\ No newline at end of file
return {"bytes": None, "filepath": None}
\ No newline at end of file
......@@ -69,7 +69,7 @@ class OpenAIService(BaseTTSService):
model=Models.tts,
voice=voice,
input=text,
response_format="mp3"
response_format="wav"
)
audio_bytes = response.content
......
......@@ -22,7 +22,7 @@ class ResponseManager:
"""Creates a consistent key for Redis to avoid conflicts."""
return f"student_response:{student_id}"
def store_response(self, student_id: str, text: str, audio_filename: Optional[str] = None, audio_bytes: Optional[bytes] = None) -> None:
def store_response(self, student_id: str, text: str, audio_filepath: Optional[str] = None, audio_bytes: Optional[bytes] = None) -> None:
"""Stores a response for a specific student_id in Redis."""
key = self._get_key(student_id)
......@@ -31,7 +31,7 @@ class ResponseManager:
payload = {
"text": text,
"audio_filename": audio_filename,
"audio_filepath": audio_filepath,
"audio_bytes_b64": encoded_audio
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment