"""Topic extraction endpoints""" from fastapi import APIRouter, HTTPException from datetime import datetime import logging from services.topic_similarity_service import topic_similarity_service from models.topic import ( TopicRequest, TopicResponse, BatchTopicRequest, BatchTopicResponse, ) router = APIRouter() logger = logging.getLogger(__name__) @router.post("/extract", response_model=TopicResponse, tags=["Topic Extraction"]) async def extract_topic(request: TopicRequest): """ Find the most similar topic from predefined topics for a given text/argument - **text**: The input text or argument to find similar topic for (5-5000 chars) Returns the most similar topic from the predefined list """ try: # Find most similar topic result = topic_similarity_service.find_most_similar_topic(request.text) topic = result["topic"] # Build response response = TopicResponse( text=request.text, topic=topic, timestamp=datetime.now().isoformat() ) logger.info(f"Most similar topic found: {topic[:50]}... (similarity: {result['similarity']:.4f})") return response except ValueError as e: logger.error(f"Validation error: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"Topic similarity error: {str(e)}") raise HTTPException(status_code=500, detail=f"Topic similarity search failed: {str(e)}") @router.post("/batch-extract", response_model=BatchTopicResponse, tags=["Topic Extraction"]) async def batch_extract_topics(request: BatchTopicRequest): """ Find the most similar topics from predefined topics for multiple texts/arguments - **texts**: List of texts to find similar topics for (max 50) Returns the most similar topics from the predefined list for all texts """ try: # Batch find similar topics topics = topic_similarity_service.batch_find_similar_topics(request.texts) # Build response results = [] timestamp = datetime.now().isoformat() for i, text in enumerate(request.texts): if topics[i] is not None: results.append( TopicResponse( text=text, topic=topics[i], timestamp=timestamp ) ) else: # Skip failed searches or handle as needed logger.warning(f"Failed to find similar topic for text at index {i}") logger.info(f"Batch topic similarity search completed: {len(results)}/{len(request.texts)} successful") return BatchTopicResponse( results=results, total_processed=len(results), timestamp=timestamp ) except ValueError as e: logger.error(f"Validation error: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"Batch topic similarity error: {str(e)}") raise HTTPException(status_code=500, detail=f"Batch topic similarity search failed: {str(e)}")