2020from pypdf .errors import FileNotDecryptedError as PdfFileNotDecryptedError
2121from striprtf import striprtf
2222
23- from ...types import IndexingException , SourceItem , TaskProcException , TaskProcFatalException
23+ from ...types import IndexingException , SourceItem , TaskProcClientException , TaskProcException , TaskProcFatalException
2424from .task_proc import (
2525 OCR_TASK_TYPE ,
2626 SPEECH_TO_TEXT_TASK_TYPE ,
3535logger = logging .getLogger ('ccb.doc_loader' )
3636PDF_IMAGES_BATCH_SIZE = 25
3737PDF_IMAGES_MAX_SIZE = 100 * 1024 * 1024 # 100 MiB in bytes
38- # todo: reduce the frequency of this check ?
38+ # todo: cache it across processes ?
3939IS_OCR_AVAILABLE = is_task_type_available (OCR_TASK_TYPE )
4040IS_STT_AVAILABLE = is_task_type_available (SPEECH_TO_TEXT_TASK_TYPE )
4141
@@ -60,7 +60,7 @@ def _load_pdf(file: BytesIO, source: SourceItem) -> str:
6060
6161 for page in pdf_reader .pages :
6262 text = page .extract_text ().strip ()
63- ocr_outputs = []
63+ page_ocr_outputs = []
6464
6565 if IS_OCR_AVAILABLE :
6666 for i in range (0 , len (page .images ), PDF_IMAGES_BATCH_SIZE ):
@@ -87,12 +87,12 @@ def _load_pdf(file: BytesIO, source: SourceItem) -> str:
8787 try :
8888 ocr_tp_outputs = asyncio .run (do_ocr (source .userIds [0 ], file_ids_map .values ())) # pyright: ignore[reportArgumentType]
8989 asyncio .run (delete_temp_files (file_ids_map .values ())) # pyright: ignore[reportArgumentType]
90- except TaskProcFatalException :
90+ except TaskProcFatalException as e :
9191 # task type is not present anymore, flip the task type indicator manually
9292 # for this complete batched injest process
9393 logger .warning (
9494 'The OCR provider disappeared mid-operation, disabling OCR for this batch of'
95- f' documents including { source .reference } '
95+ f' documents including { source .reference } : { e } '
9696 )
9797 IS_OCR_AVAILABLE = False
9898 break
@@ -101,11 +101,11 @@ def _load_pdf(file: BytesIO, source: SourceItem) -> str:
101101 continue
102102
103103 # for each image batch
104- ocr_outputs += ocr_tp_outputs
104+ page_ocr_outputs += ocr_tp_outputs
105105
106- # for each page
106+ # for each page, append text then its OCR outputs to preserve document order
107107 output .append (text )
108- output += ocr_outputs
108+ output += page_ocr_outputs
109109
110110 return '\n \n ' .join (output )
111111
@@ -192,6 +192,7 @@ def decode_source(source: SourceItem) -> str:
192192 IndexingException
193193 '''
194194
195+ global IS_OCR_AVAILABLE
195196 io_obj : BytesIO | None = None
196197 try :
197198 # .pot files are powerpoint templates but also plain text files,
@@ -200,16 +201,36 @@ def decode_source(source: SourceItem) -> str:
200201 raise IndexingException ('PowerPoint template files (.pot) are not supported' )
201202
202203 try :
203- if IS_OCR_AVAILABLE and source .type .startswith ('image/' ):
204- return asyncio .run (do_ocr (source .userIds [0 ], [source .file_id ]))[0 ]
205- if IS_STT_AVAILABLE and source .type .startswith ('audio/' ):
206- return asyncio .run (do_transcription (source .userIds [0 ], source .file_id ))
207- except TaskProcException as e :
208- # todo: convert this to error obj return
209- # todo: short circuit all other ocr/transcription files when a fatal error arrives
210- # todo: maybe with a global ttl, with a retryable tag
204+ if source .type .startswith ('image/' ):
205+ if IS_OCR_AVAILABLE :
206+ return asyncio .run (do_ocr (source .userIds [0 ], [source .file_id ]))[0 ]
207+ raise IndexingException (
208+ f'Image file ({ source .reference } ) cannot be processed since OCR task type is not present'
209+ )
210+ if source .type .startswith ('audio/' ):
211+ if IS_STT_AVAILABLE :
212+ return asyncio .run (do_transcription (source .userIds [0 ], source .file_id ))
213+ raise IndexingException (
214+ f'Audio file ({ source .reference } ) cannot be processed since Speech-to-Text task type is not present'
215+ )
216+ except TaskProcFatalException as e :
217+ logger .warning (
218+ 'The OCR provider disappeared mid-operation, disabling OCR for this batch of'
219+ f' documents including { source .reference } : { e } '
220+ )
221+ IS_OCR_AVAILABLE = False
222+ raise IndexingException ( # noqa: B904
223+ f'Image file ({ source .reference } ) cannot be processed since OCR task type is not present'
224+ )
225+ except TaskProcClientException as e :
211226 logger .warning (f'OCR task failed for source file ({ source .reference } ): { e } ' )
212227 raise IndexingException (f'OCR task failed for source file ({ source .reference } ): { e } ' ) # noqa: B904
228+ except TaskProcException as e :
229+ logger .warning (f'OCR task failed for source file ({ source .reference } ), it will be retried: { e } ' )
230+ raise IndexingException ( # noqa: B904
231+ f'OCR task failed for source file ({ source .reference } ), it will be retried: { e } ' ,
232+ retryable = True ,
233+ )
213234 except ValueError :
214235 # should not happen
215236 logger .warning (f'Unexpected ValueError for source file ({ source .reference } )' )
0 commit comments