Enhancement: Switch all indexing to use rich - #12193
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #12193 +/- ##
==========================================
+ Coverage 98.12% 98.13% +0.01%
==========================================
Files 454 454
Lines 25896 25903 +7
Branches 2259 2203 -56
==========================================
+ Hits 25410 25420 +10
+ Misses 486 483 -3
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Unless I'm missing something, we didn't test document_llmindex anyway. Makes sense, given it is quite basic. I could |
|
Cool, Im testing the other one now and will do this too, I'll leave the decision about e.g. copilot reviews to you |
|
Oh wait, I think you said you did them already 👍 |
shamoon
left a comment
There was a problem hiding this comment.
This one LGTM!
Indexing documents... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 63/63 0:00:00 0:00:00Indexing documents... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 63/63 0:00:01 0:00:00(llmindex looks exactly the same as regular one =)
There was a problem hiding this comment.
Pull request overview
This PR transitions the document and LLM indexing flows away from tqdm and toward rich progress output, by injecting progress tracking via an iterable wrapper instead of coupling progress bars to the core indexing loops.
Changes:
- Replace
tqdmusage in indexing loops with aniter_wrappercallable that can either track progress (CLI) or act as a no-op (tasks/API). - Update the
document_indexanddocument_llmindexmanagement commands to usePaperlessCommand.track()(rich) for progress display. - Update call sites to match the new indexing/task function signatures (remove
progress_bar_disable).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/paperless_ai/indexing.py |
Adds a generic iterable wrapper hook to update_llm_index and removes tqdm usage. |
src/paperless/views.py |
Updates the async LLM index trigger call to match the updated task signature. |
src/documents/tasks.py |
Adds iterable wrapper hooks to reindexing and LLM indexing task flow; removes tqdm usage in reindexing. |
src/documents/management/commands/document_llmindex.py |
Switches to PaperlessCommand and uses self.track() to provide rich progress for LLM indexing. |
src/documents/management/commands/document_index.py |
Switches to PaperlessCommand and uses self.track() to provide rich progress for Whoosh reindexing. |
Comments suppressed due to low confidence (3)
src/documents/tasks.py:610
llmindex_indexis a Celery task, but it now exposes aniter_wrapperparameter that is meant to be a Python callable. With the current Celery pickle serializer, only certain callables are picklable (typically top-level functions); lambdas/closures/bound methods (likeself.track) won’t serialize reliably, so passing this via.delay()would likely break at runtime. Consider keeping the task signature strictly serializable and movingiter_wrapperto a non-task helper (task calls helper with_identity, management commands call helper withself.track).
def llmindex_index(
*,
iter_wrapper: IterWrapper[Document] = _identity,
rebuild=False,
scheduled=True,
auto=False,
) -> None:
src/paperless_ai/indexing.py:40
IterWrapper/_identityare introduced here, but the same generic wrapper + identity function are also defined insrc/documents/tasks.py. Duplicating these utilities across modules increases the chance they’ll drift (e.g., different typing/behavior). Consider moving this type alias + helper into a small shared module (or re-exporting from one place) so both indexing paths use the same definition.
_T = TypeVar("_T")
IterWrapper = Callable[[Iterable[_T]], Iterable[_T]]
def _identity(iterable: Iterable[_T]) -> Iterable[_T]:
return iterable
src/documents/tasks.py:82
IterWrapperand_identityare now defined in this module, but equivalent definitions were also added inpaperless_ai/indexing.py. To avoid divergence over time (typing tweaks, behavior changes), consider centralizing this wrapper type + identity function in a shared utility module and importing it in both places.
_T = TypeVar("_T")
IterWrapper = Callable[[Iterable[_T]], Iterable[_T]]
if settings.AUDIT_LOG_ENABLED:
from auditlog.models import LogEntry
logger = logging.getLogger("paperless.tasks")
def _identity(iterable: Iterable[_T]) -> Iterable[_T]:
return iterable
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
3dd4064 to
f49406a
Compare
|
|
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new discussion or issue for related concerns. See our contributing guidelines for more details. |



Proposed change
Switches the 2 indexing commands to use
richand decouple the progress bar from the core logic. Uses the same idea as #12182, where the iteration is either tracked with progress or simply just the iterable. Once things are settle more,_identitycan become something shared.Closes #(issue or discussion)
Type of change
Checklist:
pre-commithooks, see documentation.