96 lines
3.3 KiB
Python
96 lines
3.3 KiB
Python
"""Celery tasks for PDF parsing."""
|
|
import logging
|
|
import hashlib
|
|
from app.core.celery_app import celery_app
|
|
from app.services.pdf_text import extract_text_from_pdf, PDFExtractionError
|
|
from app.services.parser import parse_incrementables, ParsingError
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@celery_app.task(bind=True, name="parse_pdf_task")
|
|
def parse_pdf_task(self, pdf_bytes_hex: str, filename: str, document_ref: str = None):
|
|
"""
|
|
Celery task to parse PDF incrementables asynchronously.
|
|
|
|
Args:
|
|
self: Celery task instance
|
|
pdf_bytes_hex: PDF content as hex string (to serialize)
|
|
filename: Original filename
|
|
document_ref: Optional document reference
|
|
|
|
Returns:
|
|
Dictionary with parsed data or error information
|
|
"""
|
|
task_id = self.request.id
|
|
logger.info(f"Starting PDF parse task {task_id} for {filename}")
|
|
|
|
try:
|
|
# Convert hex back to bytes
|
|
pdf_bytes = bytes.fromhex(pdf_bytes_hex)
|
|
|
|
# Calculate SHA256
|
|
file_hash = hashlib.sha256(pdf_bytes).hexdigest()
|
|
|
|
# Extract text
|
|
try:
|
|
text, page_count, extraction_method = extract_text_from_pdf(pdf_bytes)
|
|
logger.info(f"Task {task_id}: Extracted {len(text)} chars from {page_count} pages")
|
|
except PDFExtractionError as e:
|
|
logger.error(f"Task {task_id}: Extraction failed - {str(e)}")
|
|
return {
|
|
"status": "failed",
|
|
"error": "extraction_failed",
|
|
"message": str(e),
|
|
"task_id": task_id
|
|
}
|
|
|
|
# Parse incrementables
|
|
try:
|
|
parsed_data = parse_incrementables(text)
|
|
logger.info(f"Task {task_id}: Successfully parsed incrementables")
|
|
except ParsingError as e:
|
|
logger.error(f"Task {task_id}: Parsing failed - {str(e)}")
|
|
return {
|
|
"status": "failed",
|
|
"error": "parsing_failed",
|
|
"message": str(e),
|
|
"task_id": task_id
|
|
}
|
|
|
|
# Build successful response
|
|
result = {
|
|
"status": "completed",
|
|
"task_id": task_id,
|
|
"document": {
|
|
"filename": filename,
|
|
"pages": page_count,
|
|
"sha256": file_hash,
|
|
"document_ref": document_ref
|
|
},
|
|
"incrementables": {
|
|
"currency": parsed_data["currency"],
|
|
"fletes": parsed_data["fletes"],
|
|
"seguros": parsed_data["seguros"],
|
|
"almacenaje_consolidacion": parsed_data["almacenaje_consolidacion"],
|
|
"regalias": parsed_data["regalias"]
|
|
},
|
|
"extraction": {
|
|
"method": extraction_method,
|
|
"anchors_found": parsed_data["anchors_found"],
|
|
"warnings": parsed_data["warnings"]
|
|
}
|
|
}
|
|
|
|
logger.info(f"Task {task_id}: Completed successfully")
|
|
return result
|
|
|
|
except Exception as e:
|
|
logger.error(f"Task {task_id}: Unexpected error - {str(e)}", exc_info=True)
|
|
return {
|
|
"status": "failed",
|
|
"error": "unexpected_error",
|
|
"message": str(e),
|
|
"task_id": task_id
|
|
}
|