Skip to content

Lire un document (OCR)

This content is not available in your language yet.

kewos/ocr transforme une image en texte. Un module appelle une fonction ; il ne choisit jamais de moteur, ne nomme jamais de fournisseur, et n’a pas à savoir si l’instance est connectée à Internet.

L’appel

from kewos.ocr import extract_text
result = extract_text(
document, # bytes
mime_type="image/jpeg",
default=tenant_default, # the tenant's ocr.engine parameter
fallback=tenant_fallback, # the tenant's ocr.fallback_engine parameter
)
result.text # what was read
result.engine # which engine answered
result.fell_back # True when the configured engine could not serve
result.blocks # positions, when the engine provides them
result.confidence # when the engine provides it

result.engine n’est pas décoratif. Un module qui déduit un montant d’un texte lu doit pouvoir dire d’où vient ce texte, et un jour quelqu’un le lui demandera.

Les deux moteurs

MoteurOù il litCoûtAccepte
pdf_textSur la machine, rien ne sortGratuitPDF
plainSur la machine, rien ne sortGratuitPNG, JPEG, TIFF, BMP, WebP
aiVia kewos/aiFacturé à l’appelPNG, JPEG, WebP, GIF

Le PDF, et pourquoi ce n’est pas de l’OCR

La plupart des PDF d’entreprise ne sont pas des scans. Une facture produite par un logiciel de comptabilité, une facture électronique, un relevé exporté : tous portent une vraie couche de texte. La lire est exact, pas probabiliste, ne coûte rien, et ne demande ni chaîne de compilation native ni modèle.

C’est pour cette raison que pdf_text se place devant l’OCR et non à côté : payer un modèle de vision pour lire un document qui dit déjà ce qu’il contient, c’est dépenser de l’argent pour obtenir une réponse moins bonne.

result = extract_text(pdf_bytes, mime_type="application/pdf", default="pdf_text")
result.text # pages, separated by a form feed (\f)
result.confidence # None: a text layer is not a guess

plain s’appuie sur un binaire système que Kewos ne prend pas en dépendance : la plupart des installations ne feront jamais d’OCR, et leur faire porter une chaîne de compilation native pour une fonction qu’elles n’utilisent pas est un coût payé par tous au bénéfice de quelques-uns.

Le moteur sonde donc à l’enregistrement. Binaire absent, moteur non enregistré, installation intacte, et la capacité OCR annoncée comme éteinte.

ai passe par la façade IA et n’appelle jamais un fournisseur directement. C’est tout le dessin : la liste blanche de fournisseurs, le consentement de résidence des données, le quota, le journal d’audit et le cache existent une fois, dans la façade, et ce moteur en hérite en ne la contournant pas.

La sélection, et pourquoi elle est stricte

  1. Un moteur nommé explicitement gagne, ou l’appel échoue. Il n’y a pas de repli : nommer un moteur est un acte délibéré, et en servir un autre en silence répondrait à une question que personne n’a posée.
  2. Sinon, le moteur configuré du tenant (ocr.engine).
  3. Si ce moteur est absent ou refuse le type de fichier, le repli (ocr.fallback_engine), et le résultat porte fell_back=True.

Le mode dégradé se voit

from kewos.ocr import ocr_capability
ocr_capability(configured_engine="plain", fallback_engine="ai")
# {"enabled": True, "engine": "ai", "degraded": True,
# "offline": False, "costly": True, "reason": "configured-engine-missing"}

Deux faits comptent pour un exploitant qui décide d’activer l’OCR, et ils sont là : est-ce que ça marche, et est-ce que les documents quittent la machine.

Le cas qui piège tout le monde est celui-ci : le binaire est installé, donc le moteur existe, mais personne ne l’a sélectionné. La capacité répond alors enabled: false avec reason: "no-engine-configured", plutôt que d’afficher un bouton qui échouera au premier clic.

Ce que le sous-système ne fait pas

  • Il ne stocke rien. Le document reste chez l’appelant.
  • Il ne journalise jamais le texte lu, ni un extrait, ni une longueur qui trahirait un contenu. Le journal porte le moteur, le type et le résultat.
  • Il n’interprète rien. Trouver un numéro de TVA dans le texte est le travail d’un module.
  • Il ne s’exécute pas dans une requête HTTP pour un document réel. Une lecture est lente et, côté IA, sortante : les modules la passent par la file de travaux.

Ajouter un moteur

from kewos.ocr import OcrEngine, register_engine
register_engine(
OcrEngine(
name="my_engine",
read=my_callable, # (document, mime_type, language) -> OcrResult
accepts=("image/png",),
offline=True, # does the document stay on this machine?
costly=False, # does a read have a per-call price?
)
)

offline et costly ne sont pas de la documentation : la sélection les lit pour refuser de choisir toute seule un moteur distant et facturé.