2828
2929from docling .datamodel .base_models import DocumentStream
3030
31+ from docling_serve .datamodel .callback import (
32+ ProgressCallbackRequest ,
33+ ProgressCallbackResponse ,
34+ )
3135from docling_serve .datamodel .convert import ConvertDocumentsOptions
3236from docling_serve .datamodel .requests import (
3337 ConvertDocumentFileSourcesRequest ,
4549 get_converter ,
4650 get_pdf_pipeline_opts ,
4751)
48- from docling_serve .engines import get_orchestrator
49- from docling_serve .engines .async_local .orchestrator import (
50- AsyncLocalOrchestrator ,
51- TaskNotFoundError ,
52+ from docling_serve .engines .async_orchestrator import (
53+ BaseAsyncOrchestrator ,
54+ ProgressInvalid ,
5255)
56+ from docling_serve .engines .async_orchestrator_factory import get_async_orchestrator
57+ from docling_serve .engines .base_orchestrator import TaskNotFoundError
5358from docling_serve .helper_functions import FormDepends
5459from docling_serve .response_preparation import process_results
5560from docling_serve .settings import docling_serve_settings
@@ -94,7 +99,7 @@ async def lifespan(app: FastAPI):
9499 pdf_format_option = get_pdf_pipeline_opts (ConvertDocumentsOptions ())
95100 get_converter (pdf_format_option )
96101
97- orchestrator = get_orchestrator ()
102+ orchestrator = get_async_orchestrator ()
98103
99104 # Start the background queue processor
100105 queue_task = asyncio .create_task (orchestrator .process_queue ())
@@ -308,7 +313,7 @@ async def process_file(
308313 response_model = TaskStatusResponse ,
309314 )
310315 async def process_url_async (
311- orchestrator : Annotated [AsyncLocalOrchestrator , Depends (get_orchestrator )],
316+ orchestrator : Annotated [BaseAsyncOrchestrator , Depends (get_async_orchestrator )],
312317 conversion_request : ConvertDocumentsRequest ,
313318 ):
314319 task = await orchestrator .enqueue (request = conversion_request )
@@ -319,6 +324,7 @@ async def process_url_async(
319324 task_id = task .task_id ,
320325 task_status = task .task_status ,
321326 task_position = task_queue_position ,
327+ task_meta = task .processing_meta ,
322328 )
323329
324330 # Task status poll
@@ -327,7 +333,7 @@ async def process_url_async(
327333 response_model = TaskStatusResponse ,
328334 )
329335 async def task_status_poll (
330- orchestrator : Annotated [AsyncLocalOrchestrator , Depends (get_orchestrator )],
336+ orchestrator : Annotated [BaseAsyncOrchestrator , Depends (get_async_orchestrator )],
331337 task_id : str ,
332338 wait : Annotated [
333339 float , Query (help = "Number of seconds to wait for a completed status." )
@@ -342,6 +348,7 @@ async def task_status_poll(
342348 task_id = task .task_id ,
343349 task_status = task .task_status ,
344350 task_position = task_queue_position ,
351+ task_meta = task .processing_meta ,
345352 )
346353
347354 # Task status websocket
@@ -350,7 +357,7 @@ async def task_status_poll(
350357 )
351358 async def task_status_ws (
352359 websocket : WebSocket ,
353- orchestrator : Annotated [AsyncLocalOrchestrator , Depends (get_orchestrator )],
360+ orchestrator : Annotated [BaseAsyncOrchestrator , Depends (get_async_orchestrator )],
354361 task_id : str ,
355362 ):
356363 await websocket .accept ()
@@ -375,6 +382,7 @@ async def task_status_ws(
375382 task_id = task .task_id ,
376383 task_status = task .task_status ,
377384 task_position = task_queue_position ,
385+ task_meta = task .processing_meta ,
378386 )
379387 await websocket .send_text (
380388 WebsocketMessage (
@@ -389,6 +397,7 @@ async def task_status_ws(
389397 task_id = task .task_id ,
390398 task_status = task .task_status ,
391399 task_position = task_queue_position ,
400+ task_meta = task .processing_meta ,
392401 )
393402 await websocket .send_text (
394403 WebsocketMessage (
@@ -416,7 +425,7 @@ async def task_status_ws(
416425 },
417426 )
418427 async def task_result (
419- orchestrator : Annotated [AsyncLocalOrchestrator , Depends (get_orchestrator )],
428+ orchestrator : Annotated [BaseAsyncOrchestrator , Depends (get_async_orchestrator )],
420429 task_id : str ,
421430 ):
422431 result = await orchestrator .task_result (task_id = task_id )
@@ -427,4 +436,23 @@ async def task_result(
427436 )
428437 return result
429438
439+ # Update task progress
440+ @app .post (
441+ "/v1alpha/callback/task/progress" ,
442+ response_model = ProgressCallbackResponse ,
443+ )
444+ async def callback_task_progress (
445+ orchestrator : Annotated [BaseAsyncOrchestrator , Depends (get_async_orchestrator )],
446+ request : ProgressCallbackRequest ,
447+ ):
448+ try :
449+ await orchestrator .receive_task_progress (request = request )
450+ return ProgressCallbackResponse (status = "ack" )
451+ except TaskNotFoundError :
452+ raise HTTPException (status_code = 404 , detail = "Task not found." )
453+ except ProgressInvalid as err :
454+ raise HTTPException (
455+ status_code = 400 , detail = f"Invalid progress payload: { err } "
456+ )
457+
430458 return app
0 commit comments