lumnik. / scénarios Tous les scénarios · English

Paperless-ngx: la liste qui bouge pendant la lecture est relue

Objectif Lire tous les correspondants d'une archive Paperless-ngx par son API, même quand quelqu'un y travaille.

Un vrai Paperless-ngx 2.13 et 100 correspondants, lus dix par page.

manifests/lab-docker-compose.yml
# Paperless-ngx, a document management system on Django REST Framework, with its broker. SQLite, the default.name: lumnik-paperlessservices:  broker:    image: redis:7  paperless:    image: ghcr.io/paperless-ngx/paperless-ngx:2.13.5    depends_on: [broker]    environment:      PAPERLESS_REDIS: redis://broker:6379      PAPERLESS_ADMIN_USER: lumnik      PAPERLESS_ADMIN_PASSWORD: ${PAPERLESS_PASSWORD:-paperless-lab-password}      PAPERLESS_URL: http://host.docker.internal:${PAPERLESS_PORT:-9330}      PAPERLESS_SECRET_KEY: lab-only-secret-key    ports: ["127.0.0.1:${PAPERLESS_PORT:-9330}:8000"]   # this machine only
manifests/10-correspondents.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-paperless-a  connector_type: rest-generic  scopes: [archive]spec:  base_url: http://host.docker.internal:9330/api  auth:    kind: basic    username: lumnik    password_env: SCENARIO_PAPERLESS_A_PASSWORD  default_rate_limit: 1/s                              # a gentle reader: ten pages take ten seconds  endpoints:    - id: correspondents      path: /correspondents/?page_size=10      method: GET      pagination: { kind: drf-page }                   # follows $.next, reads $.results, checks $.count      target:        kind: hybrid        table: ext.scenario_paperless_a        unique_key: $.id        promote:          - { name: name, path: $.name, type: text }          - { name: documents, path: $.document_count, type: integer }
$ lm connector run scenario-paperless-a
run scheduled: 849bc650-cac4-4e43-a940-5f8ceb852500

$ lm run get 849bc650-cac4-4e43-a940-5f8ceb852500
ID        CONNECTOR             ENDPOINT        STATUS     IN   OUT  SKIPPED  DEAD-LETTERS  STARTED           ENDED             EVALUATED
849bc650  scenario-paperless-a  correspondents  Completed  159  159  0        0             2026-11-03 14:46  2026-11-03 14:46  yes
$ lm connector run scenario-paperless-a
run scheduled: 2b20a586-1f93-4067-93a7-9f4739abb7ee

$ lm run get 2b20a586-1f93-4067-93a7-9f4739abb7ee
ID        CONNECTOR             ENDPOINT        STATUS  IN  OUT  SKIPPED  DEAD-LETTERS  STARTED           ENDED             EVALUATED
2b20a586  scenario-paperless-a  correspondents  Failed  20  20   0        0             2026-11-03 14:46  2026-11-03 14:46  yes
✖ run failed: Endpoint 'correspondents': the list changed while it was read, and again when read a second time (the source declared 101 rows, then 102) — rows may be on no page; refusing to report a partial extract as a complete one (run it when the source is quieter)

Limites

  • Un correspondant supprimé reste dans la table du hub: une lecture complète ajoute et met à jour, elle n'efface pas.
  • La relecture compte deux fois les lignes lues deux fois dans IN; l'upsert n'en garde qu'une.
  • 100 correspondants fictifs, créés par le script.

Archive · documents

Les correspondants sont dans Paperless-ngx.

Il faut tous les lire, chaque nuit.

Paperless-ngx 2.13, 100 correspondants

Le problème

L'API rend la liste par pages.

  • Dix par page, numérotées.
  • Pendant ce temps, l'équipe travaille.

Ce qui n'est pas modifié

L'archive reste telle quelle.

  • Son API, un compte en lecture.
  • Aucun module, aucun réglage.

Le piège

Une suppression décale les pages.

  • Un correspondant de la page 1 disparaît.
  • Un autre ne tombe sur aucune page.

Ce qu'il a fallu écrire

pagination: { kind: drf-page }

Une ligne.

  • Le count de chaque page est vérifié.
  • S'il bouge, la liste est relue.
  • Un connecteur de 27 lignes.

Quand ça ne s'arrête pas

Le run échoue, il ne ment pas.

  • La liste bouge encore à la relecture.
  • Le message donne les deux totaux.

Ce qui a été corrigé

Un trou trouvé, une correction.

  • Avant: Completed, un correspondant manquant.
  • Maintenant: relu, ou refusé (#1771).

Essayer

Le scénario se rejoue en local.

Chaque étape est publiée avec sa sortie.

Ce scénario tourne sur lumnik Open, gratuit et open source.

Essayer lumnik Open →