API Codestral en Python
Mis à jour le 29 juillet 2026
Appeler Codestral depuis Python
Cette leçon passe de la théorie au code exécutable. Vous allez utiliser le SDK Python de Mistral AI pour interroger Codestral sur ses deux endpoints, régler les paramètres avancés qui font la différence entre une suggestion utile et une suggestion bavarde, et mettre en place les patterns qu’on retrouve dans la plupart des intégrations réelles.
Installation et configuration
Le SDK s’installe en une commande :
pip install mistralai
La clé API se récupère sur console.mistral.ai et se lit depuis l’environnement plutôt que d’être écrite en dur dans le fichier :
import os
from mistralai import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
Deux plateformes servent Codestral, et le choix se fait au moment de créer la clé. api.mistral.ai fonctionne en pay-per-use, avec facturation à l’usage : c’est la voie normale quand Codestral est une brique parmi d’autres dans une application. codestral.mistral.ai est un endpoint dédié, accessible gratuitement ou par abonnement, pensé pour l’usage direct par un développeur dans son éditeur.
Appel FIM complet
Voici un appel FIM détaillé avec tous les paramètres importants :
from mistralai import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
response = client.fim.complete(
model="codestral-latest",
prompt="def calculer_tva(prix_ht: float, taux: float = 0.20) -> float:",
suffix="prix = float(input('Prix HT: '))\nprint(f'Prix TTC: {calculer_tva(prix):.2f} EUR')",
temperature=0,
max_tokens=150,
stop=["\n\n"],
)
completion = response.choices[0].message.content
print(completion)
Décortiquer la réponse
L’objet retourné ne contient pas que le texte généré. Trois informations méritent d’être lues systématiquement en production : la complétion elle-même, la consommation de tokens qui détermine la facture, et la raison d’arrêt qui vous dit si le modèle s’est arrêté parce qu’il avait fini ou parce qu’il a heurté votre plafond.
# Accéder à la complétion générée
texte = response.choices[0].message.content
# Vérifier le nombre de tokens utilisés
tokens_prompt = response.usage.prompt_tokens
tokens_completion = response.usage.completion_tokens
tokens_total = response.usage.total_tokens
# Vérifier la raison d'arrêt
raison = response.choices[0].finish_reason # "stop", "length", etc.
Un finish_reason à "length" sur la moitié de vos appels est un signal clair : votre max_tokens est trop bas et vous livrez du code tronqué à vos utilisateurs.
Appel Chat pour la génération de code
Dès qu’il n’y a pas de curseur au milieu d’un fichier — génération complète, explication, refactoring — l’endpoint chat reprend la main. Le message système sert alors à cadrer le format de sortie, ce qui évite d’avoir à nettoyer la réponse ensuite :
response = client.chat.complete(
model="codestral-latest",
messages=[
{
"role": "system",
"content": "Vous êtes un assistant de développement Python expert. Répondez uniquement avec du code, sans explication."
},
{
"role": "user",
"content": "Écrivez une fonction Python qui valide une adresse email avec regex."
}
],
temperature=0.2,
max_tokens=500,
)
code = response.choices[0].message.content
print(code)
Paramètres avancés
Le couple min_tokens / max_tokens encadre la longueur de la sortie. Le plancher est utile quand vous générez un bloc dont vous savez qu’il ne peut pas être plus court qu’un certain volume, par exemple une fonction avec sa gestion d’erreur.
# min_tokens : force une longueur minimale de sortie
# max_tokens : limite la longueur maximale
response = client.fim.complete(
model="codestral-latest",
prompt=prompt,
suffix=suffix,
min_tokens=20,
max_tokens=300,
)
Les tokens d’arrêt jouent un rôle différent : ils arrêtent la génération sur un motif, ce qui permet de garder la complétion dans le périmètre de la fonction courante au lieu de laisser le modèle enchaîner sur la suivante.
# Arrêter la génération sur des patterns spécifiques
response = client.fim.complete(
model="codestral-latest",
prompt=prompt,
suffix=suffix,
stop=["\n\n", "\nclass ", "\ndef "], # Stopper avant une nouvelle fonction/classe
)
La température, enfin, gouverne la variabilité. À 0, la même entrée donne toujours la même sortie, ce que l’autocomplétion exige. Autour de 0.3, le modèle propose des variantes, ce qui est intéressant quand vous affichez plusieurs suggestions. À 0.7, on est dans le brainstorming de code, utile pour explorer une approche mais inadapté à un flux d’édition.
# temperature=0 : déterministe (autocomplétion)
# temperature=0.3 : légèrement créatif (suggestions multiples)
# temperature=0.7 : créatif (brainstorming de code)
response = client.fim.complete(
model="codestral-latest",
prompt=prompt,
suffix=suffix,
temperature=0.3,
top_p=0.95,
)
Deux patterns à reprendre tels quels
Le premier reproduit le comportement d’un IDE : on découpe le contenu du fichier à la position du curseur et les deux moitiés deviennent le prompt et le suffix.
def autocomplete_ide(fichier_contenu: str, position_curseur: int) -> str:
"""Simule l'autocomplétion IDE avec Codestral FIM."""
prompt = fichier_contenu[:position_curseur]
suffix = fichier_contenu[position_curseur:]
response = client.fim.complete(
model="codestral-latest",
prompt=prompt,
suffix=suffix,
temperature=0,
max_tokens=100,
stop=["\n\n", "\ndef ", "\nclass "],
)
return response.choices[0].message.content
Le second automatise la documentation d’un projet existant : vous passez une fonction, vous récupérez sa docstring, et la consigne système impose un format unique pour que le résultat s’insère sans retouche.
def generer_docstring(code_fonction: str) -> str:
"""Génère une docstring pour une fonction Python."""
response = client.chat.complete(
model="codestral-latest",
messages=[
{
"role": "system",
"content": "Générez une docstring Google-style pour la fonction suivante. Retournez UNIQUEMENT la docstring entre triple quotes."
},
{
"role": "user",
"content": code_fonction
}
],
temperature=0,
max_tokens=300,
)
return response.choices[0].message.content
Gestion des erreurs
Un appel réseau échoue tôt ou tard, et une extension d’éditeur qui plante sur une erreur de validation est pire qu’une extension sans complétion. Encadrez donc systématiquement vos appels :
from mistralai import Mistral
from mistralai.models import HTTPValidationError
try:
response = client.fim.complete(
model="codestral-latest",
prompt=prompt,
suffix=suffix,
)
except HTTPValidationError as e:
print(f"Erreur de validation : {e}")
except Exception as e:
print(f"Erreur inattendue : {e}")
Points clés à retenir
- Le SDK
mistralaiexposeclient.fim.complete()pour le FIM etclient.chat.complete()pour le chat - Les paramètres
promptetsuffixsont spécifiques à l’endpoint FIM temperature=0pour l’autocomplétion,0.2-0.7pour la génération créativestoppermet de limiter la génération à un bloc de code cohérentmin_tokensetmax_tokenscontrôlent la longueur de la sortie- Toujours gérer les erreurs HTTP dans le code de production