Skip to content

Commit 420cf26

Browse files
committed
fix location of chunks.jsonl when using the file storage target processors
Signed-off-by: Michele Dolfi <dol@zurich.ibm.com>
1 parent 26a9eb5 commit 420cf26

5 files changed

Lines changed: 39 additions & 8 deletions

File tree

docling_jobkit/connectors/opensearch/target_processor.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import json
22
from pathlib import Path
3-
from typing import Any, Union
3+
from typing import Any, Optional, Union
44

55
from opensearchpy import OpenSearch
66

@@ -85,7 +85,12 @@ def instance_requires_chunks(self) -> bool:
8585
"""True when this processor is configured as an opensearch_chunks target."""
8686
return isinstance(self._target, OpenSearchChunkTarget)
8787

88-
def begin_chunks(self, filename: str, temp_dir: Path) -> None:
88+
def begin_chunks(
89+
self,
90+
filename: str,
91+
temp_dir: Path,
92+
chunk_target_key: Optional[str] = None,
93+
) -> None:
8994
"""No file needed — each chunk is upserted directly in consume_chunk()."""
9095

9196
def consume_chunk(self, chunk: ChunkedDocumentResultItem) -> None:

docling_jobkit/connectors/target_processor.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,32 @@ def requires_chunks(cls) -> bool:
118118
"""
119119
return False
120120

121-
def begin_chunks(self, filename: str, temp_dir: Path) -> None:
121+
def begin_chunks(
122+
self,
123+
filename: str,
124+
temp_dir: Path,
125+
chunk_target_key: Optional[str] = None,
126+
) -> None:
122127
"""Called once before the first chunk of a document is streamed.
123128
124129
Default: open a temp ``{stem}.chunks.jsonl`` file for writing.
125130
DB processors that override ``requires_chunks()`` can use this to
126131
initialise per-document state instead.
132+
133+
``chunk_target_key``, when provided, is the storage path that
134+
``end_chunks`` will pass to ``upload_file()`` as *target_filename*.
135+
When omitted the bare filename (``{stem}.chunks.jsonl``) is used,
136+
which is only correct for database processors that override
137+
``end_chunks`` and never call ``upload_file()`` themselves.
127138
"""
128-
self._chunk_jsonl_path: Optional[Path] = (
129-
temp_dir / f"{Path(filename).stem}.chunks.jsonl"
130-
)
139+
stem = Path(filename).stem
140+
self._chunk_jsonl_path: Optional[Path] = temp_dir / f"{stem}.chunks.jsonl"
131141
self._chunk_jsonl_file = self._chunk_jsonl_path.open("w", encoding="utf-8")
142+
self._chunk_target_key: Optional[str] = (
143+
chunk_target_key
144+
if chunk_target_key is not None
145+
else self._chunk_jsonl_path.name
146+
)
132147

133148
def consume_chunk(self, chunk: "ChunkedDocumentResultItem") -> None:
134149
"""Called once per chunk as it is produced by the chunker.
@@ -154,6 +169,6 @@ def end_chunks(self) -> None:
154169
self._chunk_jsonl_file.close()
155170
self.upload_file(
156171
filename=self._chunk_jsonl_path, # type: ignore[arg-type]
157-
target_filename=self._chunk_jsonl_path.name, # type: ignore[union-attr]
172+
target_filename=self._chunk_target_key, # type: ignore[arg-type]
158173
content_type="application/jsonl",
159174
)

docling_jobkit/convert/export.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def stream_chunks_for_document(
7171
processors: list[BaseTargetProcessor],
7272
chunks_in_formats: bool,
7373
temp_dir: Path,
74+
chunk_target_key: str | None = None,
7475
) -> int:
7576
"""Run the streaming chunk protocol across *processors* for one document.
7677
@@ -90,6 +91,10 @@ def stream_chunks_for_document(
9091
- DB processors that override ``requires_chunks()`` always participate.
9192
- File-storage processors participate only when *chunks_in_formats* is
9293
True, and only if they are *not* database processors.
94+
95+
``chunk_target_key`` is forwarded to ``begin_chunks`` so that file-storage
96+
processors write the chunks file under the correct subdirectory path (e.g.
97+
``chunks/bo20/1016445.chunks.jsonl``). DB processors ignore it.
9398
"""
9499
if not _is_exportable_status(exportable_document.status):
95100
return 0
@@ -106,7 +111,7 @@ def stream_chunks_for_document(
106111
return 0
107112

108113
for p in chunk_processors:
109-
p.begin_chunks(filename, temp_dir)
114+
p.begin_chunks(filename, temp_dir, chunk_target_key=chunk_target_key)
110115
n = 0
111116
try:
112117
for chunk in chunker_manager.chunk_document(

docling_jobkit/convert/results.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,8 @@ def _iter_remote_documents(
650650
num_failed += 1
651651

652652
if chunk_active:
653+
_source_identity = _resolve_source_identity(task, exportable_document, idx)
654+
_stem = exportable_document.file.stem
653655
with tempfile.TemporaryDirectory(dir=work_dir) as _chunk_tmp:
654656
stream_chunks_for_document(
655657
exportable_document=final_document,
@@ -659,6 +661,7 @@ def _iter_remote_documents(
659661
processors=processors,
660662
chunks_in_formats=chunks_in_formats,
661663
temp_dir=Path(_chunk_tmp),
664+
chunk_target_key=f"{_source_identity.source_key}/{_stem}.chunks.jsonl",
662665
)
663666

664667
return processed_docs, num_succeeded, num_partially_succeeded, num_failed

docling_jobkit/convert/results_processor.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ def process_documents(self, results: Iterable[ConversionResult]):
284284
processors=processors,
285285
chunks_in_formats=self._chunks_in_formats,
286286
temp_dir=temp_dir,
287+
chunk_target_key=self._target_key(
288+
f"chunks/{name_without_ext}.chunks.jsonl"
289+
),
287290
)
288291

289292
yield f"{doc_hash} - SUCCESS"

0 commit comments

Comments
 (0)