From dff286a154b0d4167bd34af76e829b96c9dd680e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Doumouro?= Date: Thu, 3 Sep 2026 17:01:14 +0200 Subject: [PATCH] feautre(extract:docling): support docling perf settings --- extract-core/extract_core/docling_.py | 17 ++++++++++++++ extract-python/README.md | 1 + extract-python/extract_python/docling_.py | 28 +++++++++++++++-------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/extract-core/extract_core/docling_.py b/extract-core/extract_core/docling_.py index 51d1ad5..212b1ab 100644 --- a/extract-core/extract_core/docling_.py +++ b/extract-core/extract_core/docling_.py @@ -20,8 +20,14 @@ TableStructureOptions, ThreadedPdfPipelineOptions, ) +from docling.datamodel.settings import ( + BatchConcurrencySettings, + DebugSettings, + InferenceSettings, +) from icij_common.pydantic_utils import ( merge_configs, + safe_copy, tagged_union, to_lower_snake_case, ) @@ -258,12 +264,19 @@ def _default_format_opts() -> dict[InputFormat, DoclingFormatOption]: } +class DoclingSettings(BaseModel): + perf: BatchConcurrencySettings = Field(default_factory=BatchConcurrencySettings) + debug: DebugSettings = Field(default_factory=DebugSettings) + inference: InferenceSettings = Field(default_factory=InferenceSettings) + + class DoclingPipelineConfig(BasePipelineConfig): pipeline: ClassVar[PipelineType] = Field(frozen=True, default=PipelineType.DOCLING) format_options: dict[InputFormat, DoclingFormatOption] = Field( default_factory=_default_format_opts ) + settings: DoclingSettings = Field(default_factory=DoclingSettings) @classmethod @cache @@ -276,3 +289,7 @@ def supported_exts(cls) -> set[SupportedExt]: for ext in FormatToExtensions[f]: supported.add(SupportedExt(f".{ext.lower()}")) return supported + + def with_setting(self, settings: DoclingSettings) -> "DoclingPipelineConfig": + update = {"settings": settings} + return safe_copy(self, update=update) diff --git a/extract-python/README.md b/extract-python/README.md index e69de29..92e5cf5 100644 --- a/extract-python/README.md +++ b/extract-python/README.md @@ -0,0 +1 @@ +รด \ No newline at end of file diff --git a/extract-python/extract_python/docling_.py b/extract-python/extract_python/docling_.py index 6a2f4ef..a3565e8 100644 --- a/extract-python/extract_python/docling_.py +++ b/extract-python/extract_python/docling_.py @@ -10,6 +10,7 @@ from docling.datamodel.document import ConversionResult from docling.datamodel.pipeline_options import PipelineOptions +from docling.datamodel.settings import scoped from docling.document_converter import DocumentConverter, FormatOption # TODO: this is long to load improve it @@ -62,16 +63,23 @@ def __init__(self, config: DoclingPipelineConfig): async def extract_content( self, docs: Iterable[InputDoc], output_format: OutputFormat, output_path: Path ) -> AsyncGenerator[Result, None]: - docs, path_or_streams = map_and_preserve(_to_docling, docs) - outputs = self._converter.convert_all(path_or_streams, raises_on_error=False) - - sentinel = object() - while True: - res = await asyncio.to_thread(next, outputs, sentinel) - if res is sentinel: - return - doc = next(docs) - yield _to_result(res, doc, output_format, output_path=output_path) + settings = self._config.settings + logger.info("starting extraction with settings: %s", settings) + with scoped( + perf=settings.perf, debug=settings.debug, inference=settings.inference + ): + docs, path_or_streams = map_and_preserve(_to_docling, docs) + outputs = self._converter.convert_all( + path_or_streams, raises_on_error=False + ) + + sentinel = object() + while True: + res = await asyncio.to_thread(next, outputs, sentinel) + if res is sentinel: + return + doc = next(docs) + yield _to_result(res, doc, output_format, output_path=output_path) def _to_docling(docs: Iterable[InputDoc]) -> Iterator["Path | DocumentStream"]: