feat: Agregar soporte OCR con Tesseract para PDFs escaneados
- Integrar Tesseract OCR para leer PDFs escaneados automáticamente - Detectar automáticamente si el PDF tiene texto o requiere OCR - Agregar servicio ocr_service.py con funciones de OCR - Actualizar Dockerfile con tesseract-ocr, tesseract-ocr-spa y poppler-utils - Agregar variables de configuración OCR (OCR_ENABLED, OCR_LANGUAGE, OCR_DPI, OCR_TIMEOUT) - Crear endpoint de debug para ver texto extraído (/api/v1/debug/extract-text) - Agregar scripts de instalación y prueba (install_ocr.ps1, test_ocr.py, debug_pdf.ps1) - Documentación completa (OCR_SETUP.md, DOCKER_OCR.md, COMO_PROBAR.md) - Actualizar docker-compose.yml con variables de entorno OCR - Modificar pdf_text.py para usar OCR cuando sea necesario - Actualizar requirements.txt con pytesseract, Pillow, pdf2image
This commit is contained in:
87
app/api/v1/debug.py
Normal file
87
app/api/v1/debug.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""Debug endpoint to see extracted text from PDF."""
|
||||
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, status
|
||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||
import logging
|
||||
|
||||
from app.core.config import get_settings
|
||||
from app.core.security import decode_access_token
|
||||
from app.services.pdf_text import extract_text_from_pdf, PDFExtractionError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix="/v1/debug", tags=["Debug"])
|
||||
security = HTTPBearer()
|
||||
settings = get_settings()
|
||||
|
||||
|
||||
def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> str:
|
||||
"""Validate JWT token."""
|
||||
payload = decode_access_token(credentials.credentials)
|
||||
return payload.get("sub")
|
||||
|
||||
|
||||
@router.post("/extract-text")
|
||||
async def debug_extract_text(
|
||||
file: UploadFile = File(...),
|
||||
current_user: str = Depends(get_current_user)
|
||||
):
|
||||
"""
|
||||
Debug endpoint to see raw extracted text from PDF.
|
||||
Shows exactly what text was extracted and which method was used.
|
||||
"""
|
||||
# Validate file type
|
||||
if file.content_type != "application/pdf":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"Invalid file type: {file.content_type}. Only PDF files are allowed."
|
||||
)
|
||||
|
||||
# Read file
|
||||
pdf_bytes = await file.read()
|
||||
|
||||
# Validate size
|
||||
file_size_mb = len(pdf_bytes) / (1024 * 1024)
|
||||
if file_size_mb > settings.max_file_mb:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"File size ({file_size_mb:.2f} MB) exceeds maximum allowed size of {settings.max_file_mb} MB"
|
||||
)
|
||||
|
||||
# Extract text
|
||||
try:
|
||||
text, page_count, extraction_method = extract_text_from_pdf(
|
||||
pdf_bytes,
|
||||
enable_ocr=settings.ocr_enabled,
|
||||
ocr_lang=settings.ocr_language
|
||||
)
|
||||
|
||||
# Get first and last 500 characters
|
||||
text_preview_start = text[:500] if len(text) > 500 else text
|
||||
text_preview_end = text[-500:] if len(text) > 500 else ""
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"extraction_info": {
|
||||
"method": extraction_method,
|
||||
"pages": page_count,
|
||||
"total_characters": len(text),
|
||||
"total_words": len(text.split()),
|
||||
"total_lines": len(text.split('\n'))
|
||||
},
|
||||
"text_preview": {
|
||||
"first_500_chars": text_preview_start,
|
||||
"last_500_chars": text_preview_end if text_preview_end else None
|
||||
},
|
||||
"full_text": text, # Complete extracted text
|
||||
"ocr_settings": {
|
||||
"ocr_enabled": settings.ocr_enabled,
|
||||
"ocr_language": settings.ocr_language,
|
||||
"ocr_dpi": settings.ocr_dpi
|
||||
}
|
||||
}
|
||||
|
||||
except PDFExtractionError as e:
|
||||
logger.error(f"Extraction failed: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Failed to extract text from PDF: {str(e)}"
|
||||
)
|
||||
Reference in New Issue
Block a user