Spaces:
Sleeping
Sleeping
| """ | |
| OCR (Image OCR, LaTeX-OCR) router for Lily LLM API | |
| """ | |
| from fastapi import APIRouter, HTTPException, UploadFile, File, Form | |
| from typing import Optional | |
| import logging | |
| import time | |
| import os | |
| import uuid | |
| from ...models.schemas import DocumentUploadResponse, RAGResponse | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter() | |
| # ============================================================================ | |
| # 이미지 OCR 전용 API 엔드포인트 | |
| # ============================================================================ | |
| async def upload_image_document( | |
| file: UploadFile = File(...), | |
| user_id: str = Form("default_user"), | |
| document_id: Optional[str] = Form(None) | |
| ): | |
| """이미지 OCR 전용 문서 업로드""" | |
| start_time = time.time() | |
| try: | |
| # 문서 ID 생성 (제공되지 않은 경우) | |
| if not document_id: | |
| document_id = str(uuid.uuid4())[:8] | |
| # 임시 파일 저장 | |
| temp_file_path = f"./temp_image_{document_id}_{file.filename}" | |
| with open(temp_file_path, "wb") as f: | |
| content = await file.read() | |
| f.write(content) | |
| # 이미지 OCR 처리 및 벡터 스토어에 저장 | |
| try: | |
| from lily_llm_core.image_rag_processor import image_rag_processor | |
| result = image_rag_processor.process_and_store_image_document( | |
| user_id, document_id, temp_file_path | |
| ) | |
| except ImportError: | |
| result = { | |
| "success": False, | |
| "error": "Image RAG processor not available" | |
| } | |
| # 임시 파일 삭제 | |
| if os.path.exists(temp_file_path): | |
| os.remove(temp_file_path) | |
| processing_time = time.time() - start_time | |
| logger.info(f"🖼️ 이미지 OCR 문서 업로드 완료 ({processing_time:.2f}초): {file.filename}") | |
| return DocumentUploadResponse( | |
| success=result["success"], | |
| document_id=document_id, | |
| message=result.get("message", ""), | |
| chunks=result.get("chunks"), | |
| latex_count=result.get("latex_count"), | |
| error=result.get("error"), | |
| auto_response=result.get("auto_response", "") | |
| ) | |
| except Exception as e: | |
| logger.error(f"❌ 이미지 OCR 문서 업로드 실패: {e}") | |
| return DocumentUploadResponse( | |
| success=False, | |
| document_id=document_id if 'document_id' in locals() else "unknown", | |
| message="이미지 OCR 문서 업로드 중 오류가 발생했습니다.", | |
| error=str(e) | |
| ) | |
| async def generate_image_ocr_response( | |
| query: str = Form(...), | |
| user_id: str = Form("default_user"), | |
| document_id: str = Form(...) | |
| ): | |
| """이미지 OCR 기반 RAG 응답 생성""" | |
| start_time = time.time() | |
| try: | |
| # 이미지 OCR RAG 응답 생성 | |
| try: | |
| from lily_llm_core.image_rag_processor import image_rag_processor | |
| result = image_rag_processor.generate_image_rag_response( | |
| user_id, document_id, query | |
| ) | |
| except ImportError: | |
| result = { | |
| "success": False, | |
| "response": "Image RAG processor not available", | |
| "context": "", | |
| "sources": [], | |
| "search_results": 0 | |
| } | |
| processing_time = time.time() - start_time | |
| result["processing_time"] = processing_time | |
| logger.info(f"🖼️ 이미지 OCR RAG 응답 생성 완료 ({processing_time:.2f}초)") | |
| return result | |
| except Exception as e: | |
| logger.error(f"❌ 이미지 OCR RAG 응답 생성 실패: {e}") | |
| return RAGResponse( | |
| success=False, | |
| response=f"이미지 OCR RAG 응답 생성 중 오류가 발생했습니다: {str(e)}", | |
| context="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=time.time() - start_time | |
| ) | |
| async def get_image_document_info(user_id: str, document_id: str): | |
| """이미지 OCR 문서 정보 조회""" | |
| try: | |
| try: | |
| from lily_llm_core.image_rag_processor import image_rag_processor | |
| result = image_rag_processor.get_image_document_info(user_id, document_id) | |
| except ImportError: | |
| result = { | |
| "success": False, | |
| "error": "Image RAG processor not available" | |
| } | |
| return result | |
| except Exception as e: | |
| logger.error(f"❌ 이미지 OCR 문서 정보 조회 실패: {e}") | |
| return { | |
| "success": False, | |
| "error": str(e) | |
| } | |
| async def delete_image_document(user_id: str, document_id: str): | |
| """이미지 OCR 문서 삭제""" | |
| try: | |
| # 벡터 스토어에서 문서 삭제 | |
| try: | |
| from lily_llm_core.vector_store_manager import vector_store_manager | |
| success = vector_store_manager.delete_document(user_id, document_id) | |
| except ImportError: | |
| success = False | |
| if success: | |
| return { | |
| "success": True, | |
| "message": "이미지 OCR 문서가 삭제되었습니다." | |
| } | |
| else: | |
| return { | |
| "success": False, | |
| "error": "이미지 OCR 문서 삭제에 실패했습니다." | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ 이미지 OCR 문서 삭제 실패: {e}") | |
| return { | |
| "success": False, | |
| "error": str(e) | |
| } | |
| # ============================================================================ | |
| # LaTeX-OCR 전용 API 엔드포인트 | |
| # ============================================================================ | |
| async def upload_latex_document( | |
| file: UploadFile = File(...), | |
| user_id: str = Form("default_user"), | |
| document_id: Optional[str] = Form(None) | |
| ): | |
| """LaTeX-OCR 전용 문서 업로드""" | |
| start_time = time.time() | |
| try: | |
| # 문서 ID 생성 (제공되지 않은 경우) | |
| if not document_id: | |
| document_id = str(uuid.uuid4())[:8] | |
| # 임시 파일 저장 | |
| temp_file_path = f"./temp_latex_{document_id}_{file.filename}" | |
| with open(temp_file_path, "wb") as f: | |
| content = await file.read() | |
| f.write(content) | |
| # LaTeX-OCR 처리 및 벡터 스토어에 저장 | |
| try: | |
| from lily_llm_core.latex_rag_processor import latex_rag_processor | |
| result = latex_rag_processor.process_and_store_latex_document( | |
| user_id, document_id, temp_file_path | |
| ) | |
| except ImportError: | |
| result = { | |
| "success": False, | |
| "error": "LaTeX RAG processor not available" | |
| } | |
| # 임시 파일 삭제 | |
| if os.path.exists(temp_file_path): | |
| os.remove(temp_file_path) | |
| processing_time = time.time() - start_time | |
| logger.info(f"🧮 LaTeX-OCR 문서 업로드 완료 ({processing_time:.2f}초): {file.filename}") | |
| return DocumentUploadResponse( | |
| success=result["success"], | |
| document_id=document_id, | |
| message=result.get("message", ""), | |
| chunks=result.get("chunks"), | |
| latex_count=result.get("latex_count"), | |
| error=result.get("error"), | |
| auto_response=result.get("auto_response", "") | |
| ) | |
| except Exception as e: | |
| logger.error(f"❌ LaTeX-OCR 문서 업로드 실패: {e}") | |
| return DocumentUploadResponse( | |
| success=False, | |
| document_id=document_id if 'document_id' in locals() else "unknown", | |
| message="LaTeX-OCR 문서 업로드 중 오류가 발생했습니다.", | |
| error=str(e) | |
| ) | |
| async def generate_latex_ocr_response( | |
| query: str = Form(...), | |
| user_id: str = Form("default_user"), | |
| document_id: str = Form(...) | |
| ): | |
| """LaTeX-OCR 기반 RAG 응답 생성""" | |
| start_time = time.time() | |
| try: | |
| # LaTeX-OCR RAG 응답 생성 | |
| try: | |
| from lily_llm_core.latex_rag_processor import latex_rag_processor | |
| result = latex_rag_processor.generate_latex_rag_response( | |
| user_id, document_id, query | |
| ) | |
| except ImportError: | |
| result = { | |
| "success": False, | |
| "response": "LaTeX RAG processor not available", | |
| "context": "", | |
| "sources": [], | |
| "search_results": 0 | |
| } | |
| processing_time = time.time() - start_time | |
| result["processing_time"] = processing_time | |
| logger.info(f"🧮 LaTeX-OCR RAG 응답 생성 완료 ({processing_time:.2f}초)") | |
| return result | |
| except Exception as e: | |
| logger.error(f"❌ LaTeX-OCR RAG 응답 생성 실패: {e}") | |
| return RAGResponse( | |
| success=False, | |
| response=f"LaTeX-OCR RAG 응답 생성 중 오류가 발생했습니다: {str(e)}", | |
| context="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=time.time() - start_time | |
| ) | |
| async def get_latex_document_info(user_id: str, document_id: str): | |
| """LaTeX-OCR 문서 정보 조회""" | |
| try: | |
| try: | |
| from lily_llm_core.latex_rag_processor import latex_rag_processor | |
| result = latex_rag_processor.get_latex_document_info(user_id, document_id) | |
| except ImportError: | |
| result = { | |
| "success": False, | |
| "error": "LaTeX RAG processor not available" | |
| } | |
| return result | |
| except Exception as e: | |
| logger.error(f"❌ LaTeX-OCR 문서 정보 조회 실패: {e}") | |
| return { | |
| "success": False, | |
| "error": str(e) | |
| } | |
| async def delete_latex_document(user_id: str, document_id: str): | |
| """LaTeX-OCR 문서 삭제""" | |
| try: | |
| # 벡터 스토어에서 문서 삭제 | |
| try: | |
| from lily_llm_core.vector_store_manager import vector_store_manager | |
| success = vector_store_manager.delete_document(user_id, document_id) | |
| except ImportError: | |
| success = False | |
| if success: | |
| return { | |
| "success": True, | |
| "message": "LaTeX-OCR 문서가 삭제되었습니다." | |
| } | |
| else: | |
| return { | |
| "success": False, | |
| "error": "LaTeX-OCR 문서 삭제에 실패했습니다." | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ LaTeX-OCR 문서 삭제 실패: {e}") | |
| return { | |
| "success": False, | |
| "error": str(e) | |
| } | |
| # ============================================================================ | |
| # LaTeX-OCR + FAISS 통합 시스템 엔드포인트 (현재 비활성화) | |
| # ============================================================================ | |
| async def process_pdf_with_latex_faiss( | |
| file: UploadFile = File(...), | |
| user_id: str = Form("default_user"), | |
| system_type: str = Form("simple") # "simple" 또는 "integrated" | |
| ): | |
| """PDF에서 LaTeX 수식 추출 및 FAISS 저장 (현재 비활성화)""" | |
| try: | |
| # 파일 저장 | |
| from pathlib import Path | |
| upload_dir = Path("uploads/latex_ocr_faiss") | |
| upload_dir.mkdir(parents=True, exist_ok=True) | |
| file_path = upload_dir / f"{user_id}_{file.filename}" | |
| with open(file_path, "wb") as f: | |
| content = await file.read() | |
| f.write(content) | |
| # 현재 비활성화된 기능 | |
| return DocumentUploadResponse( | |
| success=False, | |
| document_id="", | |
| message="LaTeX-OCR + FAISS 기능이 현재 비활성화되어 있습니다", | |
| error="삭제된 모듈로 인해 기능이 비활성화됨" | |
| ) | |
| except Exception as e: | |
| logger.error(f"LaTeX-OCR + FAISS 처리 오류: {e}") | |
| return DocumentUploadResponse( | |
| success=False, | |
| document_id="", | |
| message="처리 중 오류가 발생했습니다", | |
| error=f"처리 중 오류가 발생했습니다: {str(e)}" | |
| ) | |
| async def search_latex_formulas( | |
| query: str = Form(...), | |
| user_id: str = Form("default_user"), | |
| document_path: Optional[str] = Form(None), | |
| system_type: str = Form("simple"), | |
| k: int = Form(5) | |
| ): | |
| """저장된 LaTeX 수식 검색 (현재 비활성화)""" | |
| try: | |
| # 현재 비활성화된 기능 | |
| return RAGResponse( | |
| success=False, | |
| response="LaTeX-OCR + FAISS 검색 기능이 현재 비활성화되어 있습니다", | |
| context="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=0.0, | |
| error="삭제된 모듈로 인해 기능이 비활성화됨" | |
| ) | |
| except Exception as e: | |
| logger.error(f"LaTeX 수식 검색 오류: {e}") | |
| return RAGResponse( | |
| success=False, | |
| response="검색 중 오류가 발생했습니다.", | |
| context="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=0.0, | |
| error=str(e) | |
| ) | |
| async def get_latex_ocr_faiss_status(): | |
| """LaTeX-OCR + FAISS 시스템 상태 확인 (현재 비활성화)""" | |
| try: | |
| return { | |
| "simple_system_initialized": False, | |
| "integrated_system_initialized": False, | |
| "status": "disabled", | |
| "message": "LaTeX-OCR + FAISS 기능이 현재 비활성화되어 있습니다" | |
| } | |
| except Exception as e: | |
| logger.error(f"상태 확인 오류: {e}") | |
| return {"status": "error", "error": str(e)} | |