CLI File Staging and Collision Handling#
Overview#
The docling convert CLI command collects, resolves, and stages source files into a flat list of Path | str objects before handing them to DocumentConverter.convert_all(). The staging logic lives in the convert() function in docling/cli/main.py, and the lower-level URL-to-path resolution lives in docling_core/utils/file.py.
Input Resolution Pipeline#
All source arguments are iterated inside a tempfile.TemporaryDirectory() context . For each src string:
- HTTP URL + HTML source — passed through as a bare
str. - Local directory — recursively expanded by
_iter_input_paths_from_directory(), which usesrglob("*"), filters by extension via_name_matches_format(), and skips temporary Word lock files (~$*.docx) . - Local file (HTML) — appended as a
Pathdirectly without further download . - Local file (all other formats) — passed through
resolve_source_to_path()even though it already exists locally; see Staging viaresolve_source_to_pathbelow . - Remote URL (non-HTML) — passed to
resolve_source_to_path(), which downloads the file into the sharedtempdir.
Format filtering via --from is applied during directory expansion (step 2) and at the DocumentConverter level via allowed_formats=from_formats .
Staging via resolve_source_to_path#
resolve_source_to_path() in docling_core wraps the internal _resolve_source_to_path(), which:
- Calls
resolve_source_to_stream()to obtain aDocumentStream(either by HTTP download or local file read). - Derives a filename: for remote sources, it reads the
Content-Dispositionheader first, then falls back to the URL path's basename, then to a"file"fallback . - Writes the stream to
workdir / doc_stream.name— a flat path with no subdirectory structure .
The CLI passes workdir=Path(tempdir) — the single shared temporary directory — to every resolve_source_to_path() call .
Basename Collision Behavior (No Deduplication)#
There is no collision detection. When two different remote URLs or local files resolve to the same basename (e.g., both named report.pdf), the second write silently overwrites the first in workdir . The overwritten path is still added to input_doc_paths, so convert_all() processes it — but it now contains the content of whichever file was staged last.
The same silent-overwrite risk applies during output: export_documents() names every output file as {conv_res.input.file.stem}.{ext} . Two inputs sharing a stem (e.g., subdir_a/report.pdf and subdir_b/report.pdf) will produce colliding output files, with the last write winning.
Implication for directory inputs:
_iter_input_paths_from_directory()preserves full absolute paths (it yieldsPathobjects fromrglob), so directory-sourced files are not routed throughresolve_source_to_path()and are not staged intotempdir. They do not collide at the staging layer — but they can still collide at the output layer if two files in the directory share a stem.
Temporary Word File Filtering#
Lock files created by Microsoft Word (~$*.docx) are explicitly filtered out in two places: inside _iter_input_paths_from_directory() and in the top-level source loop for direct file arguments .