CoolFace
Apppublic

creativesar/face

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
content.py193 linesDownload Raw Back to api
1from fastapi import APIRouter, HTTPException, BackgroundTasks2from pydantic import BaseModel3from typing import List, Dict, Any4import logging5import os6from dotenv import load_dotenv7 8# Load environment variables9load_dotenv()10 11# Import services12from services.optimized_openrouter_rag_service import OptimizedOpenRouterRAGService13from services.qdrant_service import QdrantService14from services.openrouter_service import OpenRouterService15 16# Configure logging17logging.basicConfig(level=logging.INFO)18logger = logging.getLogger(__name__)19 20# Initialize services21openrouter_service = OpenRouterService()22qdrant_service = QdrantService()23rag_service = OptimizedOpenRouterRAGService(openrouter_service, qdrant_service)24 25router = APIRouter()26 27class ContentIndexRequest(BaseModel):28    content: str29    chapter_id: str30    section_title: str31    source_url: str32 33class BatchContentIndexRequest(BaseModel):34    contents: List[ContentIndexRequest]35 36class PersonalizeContentRequest(BaseModel):37    chapter_id: str38    user_id: str39    user_background: Dict[str, Any]40 41@router.post("/index")42async def index_content(content_data: ContentIndexRequest):43    """44    Index a single piece of content for RAG retrieval45    """46    try:47        logger.info(f"Indexing content for chapter: {content_data.chapter_id}")48 49        result = await rag_service.index_content(50            content=content_data.content,51            chapter_id=content_data.chapter_id,52            section_title=content_data.section_title,53            source_url=content_data.source_url54        )55 56        return {57            "success": True,58            "document_id": result["document_id"],59            "indexed_content_length": result["indexed_content_length"]60        }61    except Exception as e:62        logger.error(f"Error indexing content: {str(e)}")63        raise HTTPException(status_code=500, detail=str(e))64 65@router.post("/batch-index")66async def batch_index_content(content_data: BatchContentIndexRequest):67    """68    Index multiple pieces of content at once69    """70    try:71        logger.info(f"Batch indexing {len(content_data.contents)} content items")72 73        # Convert to the format expected by the service74        contents = [75            {76                "content": item.content,77                "chapter_id": item.chapter_id,78                "section_title": item.section_title,79                "source_url": item.source_url80            }81            for item in content_data.contents82        ]83 84        results = await rag_service.batch_index_content(contents)85 86        return {87            "success": True,88            "indexed_count": len(results),89            "results": results90        }91    except Exception as e:92        logger.error(f"Error batch indexing content: {str(e)}")93        raise HTTPException(status_code=500, detail=str(e))94 95@router.get("/status")96async def content_status():97    """98    Get status of the content indexing system99    """100    try:101        # Test Qdrant connection and get point count102        point_count = await qdrant_service.count_points()103 104        return {105            "status": "ready",106            "indexed_documents_count": point_count,107            "services": {108                "qdrant": await qdrant_service.test_connection(),109                "openrouter": await openrouter_service.test_connection()110            }111        }112    except Exception as e:113        logger.error(f"Error getting content status: {str(e)}")114        raise HTTPException(status_code=500, detail=str(e))115 116@router.post("/ingest-from-docs")117async def ingest_from_docs(background_tasks: BackgroundTasks):118    """119    Ingest content from the docs directory (for textbook content)120    This would read the Docusaurus docs and index them121    """122    try:123        # This would typically read from the docs directory124        # and index all the content for RAG125        docs_path = os.getenv("DOCS_PATH", "/app/docs")  # Default path in Docker126 127        if not os.path.exists(docs_path):128            raise HTTPException(status_code=404, detail=f"Docs path not found: {docs_path}")129 130        # This is a simplified version - in a real implementation, you'd want to131        # parse all the markdown files and extract content properly132        import os133        import glob134 135        markdown_files = glob.glob(f"{docs_path}/**/*.md", recursive=True)136        markdown_files += glob.glob(f"{docs_path}/**/*.mdx", recursive=True)137 138        content_items = []139        for file_path in markdown_files:140            try:141                with open(file_path, 'r', encoding='utf-8') as f:142                    content = f.read()143 144                # Extract chapter/section info from file path145                relative_path = os.path.relpath(file_path, docs_path)146                chapter_id = relative_path.replace('/', '_').replace('\\', '_').replace('.md', '').replace('.mdx', '')147                section_title = os.path.basename(file_path).replace('.md', '').replace('.mdx', '')148 149                content_items.append({150                    "content": content,151                    "chapter_id": chapter_id,152                    "section_title": section_title,153                    "source_url": f"/docs/{relative_path}"154                })155            except Exception as e:156                logger.warning(f"Could not process file {file_path}: {str(e)}")157 158        # Index all content items159        results = await rag_service.batch_index_content(content_items)160 161        return {162            "success": True,163            "processed_files": len(content_items),164            "indexed_documents": len(results),165            "results": results166        }167    except Exception as e:168        logger.error(f"Error ingesting from docs: {str(e)}")169        raise HTTPException(status_code=500, detail=str(e))170 171@router.post("/personalize")172async def personalize_content(personalize_data: PersonalizeContentRequest):173    """174    Get personalized content based on user background175    """176    try:177        # In a real implementation, this would adapt content based on user background178        # For now, we'll return the original content with some basic adaptation info179        logger.info(f"Personalizing content for chapter {personalize_data.chapter_id} for user {personalize_data.user_id}")180 181        # This would typically search for content related to the chapter_id182        # and adapt it based on the user's background183        # For now, we'll return a placeholder response184        return {185            "chapter_id": personalize_data.chapter_id,186            "user_id": personalize_data.user_id,187            "adaptation_info": "Content adaptation based on user background would happen here",188            "original_content": "Original textbook content would be returned here, adapted based on user background",189            "user_background": personalize_data.user_background190        }191    except Exception as e:192        logger.error(f"Error personalizing content: {str(e)}")193        raise HTTPException(status_code=500, detail=str(e))