Aller au contenu principal

Premier appel OCR en Python

Mis à jour le 29 juillet 2026

Passer de la théorie au code

Vous connaissez maintenant l’endpoint et ses paramètres. Il est temps d’écrire un script complet qui extrait le texte d’un PDF, de la première ligne d’import jusqu’au fichier Markdown sauvegardé sur votre disque. Nous partirons du cas le plus simple, un document public, puis nous descendrons vers ce que vous rencontrerez en pratique : des fichiers locaux, des images isolées, et des documents illustrés qu’il faut reconstruire.

Deux prérequis, déjà vus mais qu’il vaut mieux vérifier avant de perdre dix minutes sur une erreur d’authentification :

pip install mistralai
export MISTRAL_API_KEY="votre-cle-api"

Le script minimal

Voici l’extraction complète d’un PDF accessible en ligne. Trois lignes utiles : instancier le client, appeler process, parcourir les pages.

import os
from mistralai import Mistral

# Initialisation du client
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

# Appel OCR sur un PDF public
ocr_response = client.ocr.process(
    model="mistral-ocr-latest",
    document={
        "type": "document_url",
        "document_url": "https://arxiv.org/pdf/2201.04234"
    }
)

# Affichage du nombre de pages
print(f"Nombre de pages : {len(ocr_response.pages)}")

# Affichage du contenu de chaque page
for page in ocr_response.pages:
    print(f"\n--- Page {page.index + 1} ---")
    print(page.markdown)

Notez le page.index + 1 : l’index renvoyé par l’API commence à zéro, alors que vos utilisateurs comptent à partir de un. C’est un décalage anodin tant qu’on l’a en tête, et une source de confusion durable quand on le découvre dans un rapport livré au client.

Traiter un fichier de votre machine

Dans la vraie vie, le document arrive rarement par URL publique. Vous l’avez sur disque, il est confidentiel, et vous l’encodez donc en base64. Le script suivant traite une facture fournisseur et concatène l’ensemble des pages en un seul bloc de texte :

import os
import base64
from mistralai import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

# Lecture et encodage du fichier local
chemin_fichier = "facture_fournisseur.pdf"

with open(chemin_fichier, "rb") as f:
    document_base64 = base64.b64encode(f.read()).decode("utf-8")

# Appel OCR
ocr_response = client.ocr.process(
    model="mistral-ocr-latest",
    document={
        "type": "document_base64",
        "document_base64": document_base64
    }
)

# Concaténation de tout le texte
texte_complet = "\n\n".join(
    page.markdown for page in ocr_response.pages
)

print(texte_complet)

La concaténation par "\n\n".join(...) convient pour un affichage ou une recherche plein texte. En revanche, elle efface la frontière entre les pages : si vous devez plus tard citer une source ou renvoyer l’utilisateur vers la bonne page d’un contrat, conservez la structure par page plutôt que ce bloc unique.

Sauvegarder l’extraction

Chaque appel OCR coûte de l’argent et prend du temps. Relancer l’extraction du même rapport de deux cents pages parce qu’on a oublié d’enregistrer le résultat est une erreur qu’on ne commet qu’une fois. La fonction ci-dessous écrit le Markdown dans un fichier, en marquant les changements de page par un commentaire et un séparateur :

import os
import base64
from mistralai import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

def extraire_pdf(chemin_pdf: str, chemin_sortie: str) -> None:
    """Extrait le texte d'un PDF et le sauvegarde en Markdown."""

    with open(chemin_pdf, "rb") as f:
        document_base64 = base64.b64encode(f.read()).decode("utf-8")

    ocr_response = client.ocr.process(
        model="mistral-ocr-latest",
        document={
            "type": "document_base64",
            "document_base64": document_base64
        }
    )

    with open(chemin_sortie, "w", encoding="utf-8") as f:
        for page in ocr_response.pages:
            f.write(f"<!-- Page {page.index + 1} -->\n\n")
            f.write(page.markdown)
            f.write("\n\n---\n\n")

    print(f"Extraction terminée : {len(ocr_response.pages)} pages")
    print(f"Résultat sauvegardé dans : {chemin_sortie}")


# Utilisation
extraire_pdf("rapport_annuel.pdf", "rapport_annuel.md")

Le commentaire HTML <!-- Page N --> est invisible au rendu mais reste présent dans le fichier : vous pourrez le retrouver par expression régulière pour reconstituer la pagination lors de l’indexation.

Le cas d’une image isolée

OCR 4 ne se limite pas aux PDF. Une photo de facture prise au téléphone, un ticket scanné, une capture d’écran s’envoient de la même façon, avec le type image_base64 :

import os
import base64
from mistralai import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

# Encodage d'une image
with open("facture_scan.png", "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode("utf-8")

# Appel OCR sur une image
ocr_response = client.ocr.process(
    model="mistral-ocr-latest",
    document={
        "type": "image_base64",
        "image_base64": image_base64
    }
)

# Une seule "page" pour une image
print(ocr_response.pages[0].markdown)

La réponse conserve la même forme : une liste de pages, qui n’en contient ici qu’une seule. Votre code de traitement reste donc identique quel que soit le type de fichier en entrée, ce qui simplifie beaucoup les pipelines mixtes.

Reconstruire un document illustré

Le Markdown retourné référence les images sous la forme ![imageN.jpg](imageN.jpg), sans les embarquer. Si vous voulez un fichier autonome — un rapport consultable hors ligne, un aperçu à envoyer par courriel —, demandez les images en base64 et remplacez chaque référence par une data URI :

import os
import base64
import re
from mistralai import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

ocr_response = client.ocr.process(
    model="mistral-ocr-latest",
    document={
        "type": "document_url",
        "document_url": "https://arxiv.org/pdf/2201.04234"
    },
    include_image_base64=True
)

for page in ocr_response.pages:
    markdown = page.markdown

    # Remplacement des références images par le base64
    for image in page.images:
        placeholder = f"![{image.id}]({image.id})"
        data_uri = f"![{image.id}](data:image/jpeg;base64,{image.image_base64})"
        markdown = markdown.replace(placeholder, data_uri)

    print(markdown[:500])

Le fichier obtenu grossit vite, puisque le base64 pèse environ un tiers de plus que le binaire d’origine. Réservez cette reconstruction aux documents que vous devez rendre autonomes, et gardez les images en fichiers séparés dans vos pipelines d’indexation.

Avant de passer à la suite, prenez un document qui vous appartient — une facture, un contrat, une page scannée — et faites-le passer dans le script d’extraction locale. Comparez le Markdown obtenu à l’original ligne à ligne : les écarts que vous relèverez, un tableau mal reconstruit ou un en-tête absorbé dans le corps du texte, sont exactement les problèmes que les trois prochaines leçons vous apprendront à traiter.

Points clés à retenir

  • L’appel OCR se fait en 3 lignes : client, process, lecture des pages
  • Utilisez base64 pour les fichiers locaux, URL pour les documents publics
  • Le résultat est du Markdown structuré, directement exploitable
  • Les images extraites peuvent être recombinées avec le texte
  • Sauvegardez toujours vos extractions pour éviter des appels API répétés