Première requête API IA en Python : guide pratique pas à pas
Lancez votre première requête API IA en Python : installation sur Windows, venv, SDK openai via OpenRouter, streaming et gestion des erreurs pas à pas.
👁 113 lectures
Une première requête vers un modèle d’IA en Python tient en dix lignes de code : vous installez la bibliothèque openai, configurez l’adresse et votre clé, transmettez une liste de messages et récupérez la réponse. Ce guide détaille l’ensemble du processus depuis l’installation de Python sur Windows jusqu’au streaming, à la gestion des erreurs et aux tentatives automatiques (retry). Chaque script a été exécuté le 4 octobre 2026 sur Windows 11 avec Python 3.13.15 via OpenRouter, avec les résultats réels à l’appui. Il s’agit de la troisième étape du parcours API IA de zéro.
Environnement de test (4 octobre 2026)
- Windows 11 Pro, Python 3.13.15, bibliothèques : openai 3.24.0, python-dotenv 1.2.4, pydantic 2.13.5.
- Node.js 26.10 avec la bibliothèque openai 7.27.0 (variante JavaScript disponible en fin d’article).
- Accès aux modèles : OpenRouter, modèle par défaut
openai/gpt-6-luna(environ 0,0894 EUR / 0,4472 EUR pour un million de tokens, soit 0,10 / 0,50 USD - conversion indicative basée sur le taux de référence de la BCE du 12/10/2026 : https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml). - Coût global de l’ensemble des exécutions de cet article : environ 0,0045 EUR (0,005 USD).
Installer Python sur Windows
- Rendez-vous sur python.org/downloads et téléchargez le programme d’installation officiel pour Windows (Python 3.13 ou une version plus récente ; la bibliothèque openai requiert au minimum la version 3.10).
- Sur le premier écran de l’installateur, cochez impérativement la case Add python.exe to PATH. Sans cela, votre terminal ne pourra pas localiser Python.
- Option pour les adeptes de la ligne de commande :
winget install Python.Python.3.13. - Ouvrez un nouveau terminal (PowerShell ou Terminal Windows) et vérifiez l’installation avec :
python --version. Le numéro de version doit s’afficher à l’écran.
Si le Microsoft Store s’ouvre à la place, allez dans Paramètres → Applications → Paramètres avancés des applications → Alias d’exécution d’application, puis désactivez les alias python.exe et python3.exe.
Créer un environnement virtuel (venv)
Un environnement virtuel venv isole les bibliothèques d’un projet pour éviter que les dépendances d’un projet A n’interfèrent avec celles d’un projet B. La configuration ne se fait qu’une seule fois par projet :
mkdir mon-api
cd mon-api
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install openai python-dotenv
Une fois l’environnement activé, la mention (.venv) apparaît en tête de ligne dans votre console. Si PowerShell bloque l’exécution du script d’activation, exécutez une fois la commande Set-ExecutionPolicy -Scope CurrentUser RemoteSigned. Dans Git Bash, utilisez source .venv/Scripts/activate, et sous Linux ou macOS la commande source .venv/bin/activate.
Placez votre clé dans un fichier nommé .env situé à la racine du dossier du projet (une seule ligne : OPENROUTER_API_KEY=sk-or-v1-...). La procédure pour l’obtenir et la sécuriser est détaillée dans le guide Clé API : comment l’obtenir et la protéger.
Envoyer votre première requête
Le code exploite la bibliothèque officielle OpenAI tout en pointant vers l’URL d’OpenRouter. Le format de requête restant identique, une seule clé donne accès aux modèles d’OpenAI, d’Anthropic, de Google, de DeepSeek et à des centaines d’autres options. Remplacer un modèle ne nécessite de modifier qu’une chaîne de caractères.
"""Premiere requete vers un modele d'IA via OpenRouter (SDK openai)."""
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv() # charge les variables depuis le fichier .env du repertoire courant
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
# Note : le prompt original a ete teste en polonais ("Odpowiadasz po polsku, krotko i konkretnie.", "Wyjasnij w dwoch zdaniach, czym jest API.")
odpowiedz = client.chat.completions.create(
model=os.getenv("MODEL", "openai/gpt-6-luna"),
messages=[
{"role": "system", "content": "Vous repondez de maniere courte et precise."},
{"role": "user", "content": "Expliquez en deux phrases ce qu'est une API."},
],
)
print(odpowiedz.choices[0].message.content)
print("---")
print("modele:", odpowiedz.model)
print("tokens d'entree:", odpowiedz.usage.prompt_tokens)
print("tokens de sortie:", odpowiedz.usage.completion_tokens)
szczegoly = odpowiedz.usage.completion_tokens_details
if szczegoly and szczegoly.reasoning_tokens:
print(" dont tokens de reflexion:", szczegoly.reasoning_tokens)
koszt = getattr(odpowiedz.usage, "cost", None) # OpenRouter ajoute le cout en USD
if koszt is not None:
print(f"cout: {koszt:.6f} USD")
Détail du fonctionnement ligne par ligne :
load_dotenv()charge la clé du fichier.envdans les variables d’environnement ;OpenAI(base_url=..., api_key=...)initialise le client - sans le paramètrebase_url, l’appel viserait directement les serveurs d’OpenAI ;messagescontient la liste des échanges : le rôlesystemdicte les consignes de base,usercontient la demande (pour approfondir les rôles et paramètres, consultez Prompt système, température et fenêtre de contexte) ;odpowiedz.choices[0].message.contentdonne accès au texte produit ;usagefournit le décompte des tokens, complété chez OpenRouter par le champcostindiquant le tarif en dollars.
Voici la réponse retournée lors de notre test initial (exécuté en polonais, traduite ici pour faciliter la lecture) avec le modèle par défaut GPT-6 Luna :
[Traduction du resultat obtenu lors du test initial en polonais]
Une API est un ensemble de regles et d'outils permettant a differents logiciels de communiquer entre eux. Elle definit comment envoyer des requetes et recevoir des donnees ou des fonctionnalites depuis un autre systeme.
---
modele: openai/gpt-6-luna
tokens d'entree: 40
tokens de sortie: 58
cout: 0.000033 USD (env. 0.000030 EUR)
Et le résultat pour la même consigne adressée à Gemini 3.8 Flash (en modifiant uniquement la variable MODEL) :
[Traduction du resultat obtenu lors du test initial en polonais]
Une API (Interface de Programmation d'Application) est un ensemble de regles qui permet a differents programmes et systemes de communiquer et d'echanger des donnees en toute securite. Elle agit comme un intermediaire, permettant a une application d'exploiter les fonctionnalites ou ressources d'une autre sans devoir connaitre sa structure interne.
---
modele: google/gemini-3.8-flash
tokens d'entree: 29
tokens de sortie: 462
dont tokens de reflexion: 390
cout: 0.001754 USD (env. 0.001569 EUR)
Le modèle Gemini a produit 462 tokens de sortie pour deux phrases, car 390 d’entre eux correspondent à son raisonnement interne (thinking tokens). Cette phase de calcul préalable est facturée au même titre que le texte visible. Cette requête a coûté 0,001754 USD (environ 0,001569 EUR selon le taux BCE du 12/10/2026), soit 50 fois plus que sur Luna. Pour évaluer vos dépenses, fiez-vous systématiquement à l’objet usage et non à la longueur finale du texte affiché. Plus de précisions dans le dossier Tokens IA : fonctionnement et calcul des coûts.
Activer le streaming pour afficher la réponse en direct
Par défaut, l’application patiente jusqu’à la fin de la génération avant d’obtenir l’intégralité du texte. Grâce au streaming, les fragments de réponse s’affichent au fur et à mesure, comme sur ChatGPT, un comportement indispensable pour les interfaces de discussion.
"""Streaming : la reponse s'affiche au fil de l'eau."""
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key=os.environ["OPENROUTER_API_KEY"])
# Note : prompt teste initialement en polonais ("Podaj 5 pomyslow na nazwe bloga o gotowaniu. Tylko lista.")
strumien = client.chat.completions.create(
model=os.getenv("MODEL", "openai/gpt-6-luna"),
messages=[{"role": "user", "content": "Donnez 5 idees de noms pour un blog de cuisine. Uniquement la liste."}],
stream=True,
stream_options={"include_usage": True}, # le dernier bloc transmettra le compte des tokens
)
for kawalek in strumien:
if kawalek.choices and kawalek.choices[0].delta.content:
print(kawalek.choices[0].delta.content, end="", flush=True)
if kawalek.usage: # arrive a la toute fin
print(f"\n--- tokens: {kawalek.usage.prompt_tokens} entree, {kawalek.usage.completion_tokens} sortie")
[Traduction indicative de la reponse obtenue lors du test en polonais]
1. Direct de la Poele
2. Une Pincee de Saveur
3. Cuisine en Conscience
4. Du Plat a l'Assiette
5. L'Escale Culinaire
--- tokens: 20 entree, 439 sortie
En streaming, la mesure des tokens n’est pas transmise d’office : il convient de déclarer stream_options={"include_usage": True} pour récupérer cette information dans le dernier bloc de données.
Gérer les erreurs de l’API et configurer les retries
En production, plusieurs incidents peuvent survenir : identifiant invalide, faute de frappe sur l’identifiant du modèle, limite de débit atteinte (erreur 429) ou indisponibilité temporaire de l’infrastructure (erreurs 5xx). Les bonnes pratiques imposent deux approches :
- Les erreurs côté client (400, 401, 403, 404) : inutile de retenter la requête, car elle échouera à l’identique ; il faut corriger le code ou la clé.
- Les erreurs temporaires (429, 500, 502, 503, pertes de connexion) : retentez avec un délai progressif (par exemple 2 s, 4 s, 8 s), complété d’un délai aléatoire (jitter) pour éviter que de multiples applications ne surchargent le serveur en même temps.
"""Gestion des erreurs API : 401, 429, 5xx et retentatives avec delai exponentiel (exponential backoff)."""
import os, sys, time, random
from dotenv import load_dotenv
import openai
from openai import OpenAI
load_dotenv()
client = OpenAI(
# BASE_URL peut pointer vers un serveur de test local
base_url=os.getenv("BASE_URL", "https://openrouter.ai/api/v1"),
api_key=os.environ.get("OPENROUTER_API_KEY", ""),
max_retries=0, # desactivation du retry integre pour illustrer la logique personnalisee
timeout=60, # en secondes ; evite qu'une requete interrompue ne bloque indefiniment
)
def zapytaj(pytanie, model, proby=4):
for proba in range(1, proby + 1):
try:
r = client.chat.completions.create(model=model, messages=[{"role": "user", "content": pytanie}])
return r.choices[0].message.content
except openai.AuthenticationError as e: # 401 - cle invalide ou inactive
sys.exit(f"401: verifiez la cle API ({e.message})")
except openai.PermissionDeniedError as e: # 403 - acces refuse (restriction geographique, moderation)
sys.exit(f"403: acces refuse ({e.message})")
except openai.NotFoundError as e: # 404 - modele introuvable ou URL incorrecte
sys.exit(f"404: modele ou adresse introuvable ({e.message})")
except openai.BadRequestError as e: # 400 - parametres ou corps de requete incorrects
sys.exit(f"400: corrigez la requete ({e.message})")
except (openai.RateLimitError, openai.InternalServerError,
openai.APIConnectionError, openai.APITimeoutError) as e:
# 429 (limite depassee / solde insuffisant), 5xx (panne serveur), coupure reseau
if proba == proby:
raise
przerwa = 2 ** proba + random.random() # 2, 4, 8 s + fraction aleatoire
kod = getattr(e, "status_code", "reseau")
print(f"[tentative {proba}] erreur {kod}, attente {przerwa:.1f} s...")
time.sleep(przerwa)
except openai.APIStatusError as e: # autres statuts (ex: 402 solde epuise sur OpenRouter)
sys.exit(f"{e.status_code}: {e.message}")
if __name__ == "__main__":
model = sys.argv[1] if len(sys.argv) > 1 else os.getenv("MODEL", "openai/gpt-6-luna")
print(zapytaj("Combien font 17 * 23 ? Donnez uniquement le chiffre.", model))
Quatre cas de figure ont été simulés. Une requête standard :
391
Une clé erronée puis un identifiant de modèle inexistant (OpenRouter renvoie un code 400 et non 404 dans ce cas) :
401: verifiez la cle API (Error code: 401 - {'error': {'message': 'User not found.', 'code': 401}})
400: corrigez la requete (Error code: 400 - {'error': {'message': 'openai/gpt-7-nie-istnieje is not a valid model ID', 'code': 400}})
Le déclenchement d’une erreur 429 est délicat à provoquer sur commande sans saturer son compte. Un serveur local minimal a donc été configuré pour rejeter les deux premiers appels avec une 429 avant d’accepter le troisième :
"""Serveur API simule : renvoie un code 429 sur les deux premiers appels, puis 200 au troisieme.
Permet de valider la logique de retry sans consommer de credit.
Fenetre 1 : python testy/serwer_429.py
Fenetre 2 : set BASE_URL=http://127.0.0.1:8429/v1 (PowerShell: $env:BASE_URL="http://127.0.0.1:8429/v1")
python 03_bledy_i_retry.py
"""
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
compteur = {"n": 0}
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
self.rfile.read(int(self.headers.get("Content-Length", 0)))
compteur["n"] += 1
if compteur["n"] <= 2:
code, contenu = 429, {"error": {"message": "Rate limit exceeded (test)", "code": 429}}
else:
code, contenu = 200, {
"id": "test-1", "object": "chat.completion", "created": 0, "model": "test",
"choices": [{"index": 0, "finish_reason": "stop",
"message": {"role": "assistant", "content": "391"}}],
"usage": {"prompt_tokens": 10, "completion_tokens": 1, "total_tokens": 11},
}
body = json.dumps(contenu).encode()
self.send_response(code)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
print(f"requete {compteur['n']} -> {code}")
HTTPServer(("127.0.0.1", 8429), Handler).serve_forever()
[tentative 1] erreur 429, attente 2.8 s...
[tentative 2] erreur 429, attente 4.2 s...
391
Le mécanisme fonctionne comme prévu : après deux refus consécutifs espacés de 2,8 s et 4,2 s, la troisième tentative renvoie le résultat. Le SDK openai propose par ailleurs un module de relance natif (configuré par défaut sur 2 essais via le paramètre max_retries), que nous avions désactivé ici afin d’observer la gestion manuelle. Dans un cadre applicatif classique, définir max_retries=5 s’avère souvent suffisant.
Trois recommandations essentielles pour le quotidien :
- Définissez un timeout systématique. Par défaut, le client attend jusqu’à 10 minutes. Avec les modèles à raisonnement complexe, un délai de 60 secondes peut s’avérer un peu court, ajustez-le selon les contraintes de votre tâche.
- Enregistrez le coût de chaque échange. Consigner la valeur
usage.costdans un fichier de journalisation fournit une visibilité budgétaire bien plus précise que n’importe quelle estimation théorique. - Distinguez un quota atteint d’un solde épuisé. Chez OpenAI, le dépassement du budget autorisé déclenche aussi un code 429 (accompagné du message
project_spend_limit_exceeded), qu’aucune boucle de réessai automatique ne pourra résoudre.
Faire la même chose en JavaScript (Node.js)
Le SDK openai destiné à l’environnement Node.js s’articule autour d’une syntaxe très proche. Avec Node.js 26.10, installez les paquets npm install openai dotenv (versions respectives 7.27.0 et 18.0.5) et vérifiez la présence de "type": "module" dans votre fichier package.json. Le script ci-dessous effectue un appel direct, active le streaming et capture les anomalies.
// Premiere requete Node.js via OpenRouter : execution directe et streaming.
// Execution dans le repertoire : npm install puis node premiere_requete.mjs
import "dotenv/config"; // charge .env depuis le dossier en cours
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
});
const model = process.env.MODEL ?? "openai/gpt-6-luna";
// 1. Requete standard (test original mene en polonais)
const r = await client.chat.completions.create({
model,
messages: [
{ role: "system", content: "Repondez brievement." },
{ role: "user", content: "Quelle est la difference entre JavaScript et Java ? Une seule phrase." },
],
});
console.log(r.choices[0].message.content);
console.log(`--- ${r.usage.prompt_tokens} + ${r.usage.completion_tokens} tokens, cout ${r.usage.cost} USD\n`);
// 2. Streaming (test original mene en polonais)
const strumien = await client.chat.completions.create({
model,
messages: [{ role: "user", content: "Citez 3 fleuves de France. Uniquement les noms separes par une virgule." }],
stream: true,
});
for await (const kawalek of strumien) {
process.stdout.write(kawalek.choices[0]?.delta?.content ?? "");
}
console.log();
// 3. Gestion des erreurs : nom de modele inexistant
try {
await client.chat.completions.create({ model: "inconnu/inexistant", messages: [{ role: "user", content: "test" }] });
} catch (e) {
if (e instanceof OpenAI.APIError) console.log(`Erreur ${e.status}: ${e.message}`);
else throw e;
}
[Traduction indicative des reponses obtenues lors du test en polonais]
JavaScript est un langage dynamique principalement utilise dans les navigateurs et le web, tandis que Java est un langage distinct a typage statique compile pour s'executer sur la JVM.
--- 39 + 54 tokens, cout 0.0000309 USD (env. 0.0000276 EUR)
La Loire, La Seine, Le Rhone
Erreur 400: 400 inconnu/inexistant is not a valid model ID
Les ajustements par rapport à Python se résument à des détails syntaxiques : baseURL à la place de base_url, l’opérateur await devant les appels asynchrones et une boucle for await pour le streaming. Dans Node.js, votre jeton secret reste consigné dans le fichier .env et ne doit en aucun cas être injecté dans du code source exécuté côté navigateur.
Scripts complets à télécharger
Les scripts d’exemple de cet article et du cursus complet sont réunis au sein de l’archive archive-de-demarrage-api comprenant un fichier explicatif et un gabarit .env.example. Il suffit d’extraire les fichiers, d’indiquer votre clé et de lancer python 01_pierwsze_zapytanie.py.
Pour aller plus loin
- Paramétrez les réglages des modèles : Prompt système, température, fenêtre de contexte et max tokens.
- Forcez les modèles à retourner du JSON valide : Structured output pas à pas.
- Évaluez vos coûts d’usage : simulateur de coût d’API.
- Passez aux workflows automatisés : parcours concevoir des agents IA de zéro, et mise en pratique : créer son premier agent en Python.
Foire aux questions
L’usage d’OpenRouter est-il indispensable pour interroger les modèles d’OpenAI ?
Non. Si vous disposez d’un compte direct auprès d’OpenAI, retirez le paramètre base_url et indiquez la référence directe du modèle (comme gpt-6-luna). Les connexions directes vers OpenAI, Anthropic et Google sont abordées dans notre sujet dédié aux clés API.
Que signifie l’erreur ModuleNotFoundError: No module named ‘openai’ ?
Ce message apparaît lorsque le SDK est installé dans un environnement distinct de celui utilisé pour exécuter le script. Réactivez votre environnement virtuel (.venv\Scripts\Activate.ps1) puis relancez l’installation via pip, ou exécutez votre script via le chemin complet : .venv\Scripts\python.
Pourquoi le script affiche-t-il KeyError: ‘OPENROUTER_API_KEY’ ?
L’interpréteur ne détecte pas votre clé secrète. Assurez-vous que le fichier est bien nommé .env sans extension résiduelle (Windows ajoute parfois une extension .txt cachée), qu’il se trouve dans votre dossier d’exécution et qu’aucun espace n’entoure le symbole égal.
Faut-il privilégier l’API Chat Completions ou l’API Responses ?
Bien qu’OpenAI mette en avant l’API Responses pour les nouvelles intégrations, l’interface Chat Completions demeure pleinement opérationnelle. Elle constitue le standard universel reconnu par OpenRouter, DeepSeek, Mistral ainsi que les moteurs locaux comme Ollama. Pour l’apprentissage, Chat Completions garantit une portabilité immédiate de votre code.
Combien coûte l’expérimentation d’une API d’IA ?
Quelques centimes d’euro suffisent pour démarrer. L’ensemble des exécutions documentées ici a coûté environ 0,005 USD (soit moins d’un demi-cent d’euro). Par ailleurs, les variantes gratuites proposées sur OpenRouter (portant la mention :free) ainsi que les accès gratuits de l’API Gemini permettent de s’entraîner sans aucun débours.


