Aller au contenu

Interagir avec des API REST en Python (Requests)

Mise à jour :

logo python

Les API REST sont aujourd’hui omniprésentes : services de géolocalisation, paiements en ligne, données météorologiques, réseaux sociaux… La capacité à communiquer avec ces interfaces depuis Python est devenue essentielle pour tout développeur. Qu’il s’agisse d’automatiser des processus métier, de récupérer des données externes ou d’intégrer des services tiers dans vos applications, les API REST constituent le pont qui relie votre code au monde extérieur. La bibliothèque requests de Python transforme cette communication en une tâche intuitive et élégante, permettant d’effectuer des requêtes HTTP complexes avec seulement quelques lignes de code.

Comprendre les bases d’une API REST

Avant d’écrire la moindre ligne de code, il est essentiel de bien comprendre comment fonctionne une API REST. Ces interfaces permettent à des programmes d’échanger des données en s’appuyant sur le protocole HTTP, celui-là même qui fait fonctionner le web.

Ressources et endpoints

Une API REST expose des ressources (utilisateurs, machines, services…) accessibles via des endpoints (URL). Par exemple, l’URL suivante :

Terminal window
https://api.exemple.com/v1/servers

peut renvoyer la liste des machines virtuelles disponibles sur une plateforme.

Méthodes HTTP

Chaque opération est liée à une méthode HTTP spécifique :

  • GET : lire des données
  • POST : créer une ressource
  • PUT : remplacer une ressource existante
  • PATCH : modifier partiellement une ressource
  • DELETE : supprimer une ressource

Ces méthodes sont utilisées pour décrire l’intention de l’appel.

Structure JSON

La majorité des API REST échangent des données au format JSON, lisible et léger. Exemple de réponse :

{
"id": 42,
"name": "webserver-prod",
"status": "running"
}

Codes de retour HTTP

À chaque appel, l’API renvoie un code de statut qui indique le résultat :

  • 200 OK : requête réussie
  • 201 Created : ressource créée
  • 204 No Content : suppression réussie, sans contenu
  • 400 Bad Request : syntaxe incorrecte
  • 401 Unauthorized : clé ou jeton manquant/invalide
  • 404 Not Found : ressource introuvable
  • 500 Internal Server Error : erreur côté serveur

Authentification

Pour des raisons de sécurité, la majorité des API nécessitent une clé d’API ou un jeton Bearer :

Authorization: Bearer eyJhbGciOiJIUzI1...

Ces éléments doivent être transmis dans les headers HTTP, et ne jamais être codés en dur dans les scripts.

Plus d’informations sur les API REST

Préparer son environnement Python

Avant de consommer des API REST en Python, il faut configurer un environnement propre, sécurisé et prêt pour l’automatisation. Voici les étapes à suivre.

Créer un environnement virtuel

Créez un environnement virtuel avec venv pour isoler vos dépendances :

Terminal window
python -m venv venv
source venv/bin/activate

Installer la bibliothèque requests

Le module requests est la bibliothèque la plus simple et la plus utilisée pour faire des appels HTTP en Python. Pour l’installer :

Terminal window
pip install requests

Ce module gère les méthodes HTTP, les entêtes, les erreurs, l’encodage JSON, etc.

Créer une structure de script claire

Organisez vos scripts avec une structure modulaire :

Terminal window
mon_script_api/
├── main.py
├── api_utils.py
└── .env
  • main.py : point d’entrée du script
  • api_utils.py : fonctions réutilisables (authentification, requêtes)
  • .env : fichier contenant les clés d’API ou les jetons d’accès

Utiliser un fichier .env pour les secrets

Pour éviter de stocker des identifiants directement dans le code, stockez-les dans un fichier .env :

Terminal window
API_KEY=sk_test_abc123
BASE_URL=https://api.exemple.com

Et lisez-les dans votre script avec la bibliothèque python-dotenv :

Terminal window
pip install python-dotenv

Dans le script :

from dotenv import load_dotenv
import os
load_dotenv()
api_key = os.getenv("API_KEY")

Pour éviter de commettre ce fichier dans Git, ajoutez .env à votre .gitignore.

Utiliser la bibliothèque requests

La bibliothèque requests simplifie les appels HTTP en Python. Voici comment l’utiliser pour interagir avec une API REST.

Pour apprendre à l’utiliser, nous allons utiliser JSONPlaceholder. C’est une API REST factice gratuite qui simule des endpoints courants.

Lire une ressource avec GET

Pour récupérer une ressource, utilisez la méthode GET :

import requests
url = "https://jsonplaceholder.typicode.com/todos/1"
response = requests.get(url)
print(response.json())

Résultat attendu :

{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": False
}

Créer une tâche avec POST

Pour créer une nouvelle ressource, utilisez la méthode POST :

payload = {
"userId": 1,
"title": "Créer un playbook Ansible",
"completed": False
}
response = requests.post("https://jsonplaceholder.typicode.com/todos", json=payload)
print(response.json())

Même si la création est fictive, l’API renvoie un objet JSON contenant un ID simulé.

{
"userId": 1,
"title": "Créer un playbook Ansible",
"completed": False,
"id": 201
}

Modifier une tâche avec PUT

Pour remplacer une ressource existante, utilisez la méthode PUT :

update = {
"userId": 1,
"title": "Tâche mise à jour",
"completed": True
}
response = requests.put("https://jsonplaceholder.typicode.com/todos/1", json=update)
print(response.json())

Vous devriez obtenir une réponse similaire à celle-ci :

{
"userId": 1,
"id": 1,
"title": "Tâche mise à jour",
"completed": True
}

Mise à jour partielle avec PATCH

Pour modifier partiellement une ressource, utilisez la méthode PATCH :

partial = {"completed": False}
response = requests.patch("https://jsonplaceholder.typicode.com/todos/1", json=partial)
print(response.json())

La réponse contiendra uniquement les champs modifiés :

{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": False
}

Supprimer une tâche avec DELETE

Pour supprimer une ressource, utilisez la méthode DELETE :

response = requests.delete("https://jsonplaceholder.typicode.com/todos/1")
print(f"Code de statut : {response.status_code}")

En général, l’API renvoie un 204 No Content ou 200 OK sans contenu.

Gérer les erreurs et exceptions

Lorsque vous consommez des API, il est essentiel de gérer les erreurs pour rendre vos scripts robustes, surtout dans un environnement d’infrastructure automatisé. Cela évite que des appels échoués passent inaperçus ou génèrent des comportements inattendus.

Vérifier les codes de statut HTTP

Chaque réponse d’API contient un code de statut HTTP. Utilisez-les pour détecter les erreurs :

response = requests.get("https://jsonplaceholder.typicode.com/todos/1")
if response.status_code == 200:
print("Succès :", response.json())
elif response.status_code == 404:
print("Ressource non trouvée.")
else:
print(f"Erreur : {response.status_code}")

Ou utilisez directement :

if response.ok:
# code 2xx

Cela est équivalente à vérifier si le code de statut est dans la plage 2xx.

Lever automatiquement les erreurs

Pour simplifier la détection, utilisez raise_for_status() :

try:
response = requests.get("https://api.exemple.com/data")
response.raise_for_status()
print(response.json())
except requests.exceptions.HTTPError as e:
print(f"Erreur HTTP : {e}")

Cette méthode déclenche une exception si le code HTTP n’est pas dans la plage 2xx.

Ici, le code lève une exception HTTPError si la requête échoue, ce qui permet de capturer les erreurs réseau ou de statut HTTP sans avoir à vérifier manuellement le code de statut.

Terminal window
Erreur HTTP : 410 Client Error: Gone for url: https://api.exemple.com/data

Capturer les erreurs réseau

Les problèmes de réseau ou d’URL incorrectes doivent être capturés avec RequestException :

try:
response = requests.get("https://mauvaise-url")
response.raise_for_status()
except requests.exceptions.ConnectionError:
print("Erreur de connexion")
except requests.exceptions.Timeout:
print("Délai d’attente dépassé")
except requests.exceptions.RequestException as e:
print(f"Erreur générale : {e}")

Ce code gère les erreurs de connexion, les délais d’attente et les autres exceptions liées aux requêtes.

Terminal window
Erreur de connexion

Ajouter des délais d’attente (timeout)

Pour éviter que votre script ne reste bloqué en cas d’API lente :

requests.get("https://jsonplaceholder.typicode.com/todos/1", timeout=5)

Cela déclenche une exception après 5 secondes d’attente.

Journaux d’erreur (logging)

Dans un script d’automatisation, loguez les erreurs au lieu de juste les afficher :

import logging
logging.basicConfig(filename='api.log', level=logging.ERROR)
try:
r = requests.get("https://api.exemple.com/data")
r.raise_for_status()
except requests.exceptions.RequestException as e:
logging.error(f"Appel échoué : {e}")

Plus d’informations sur la gestion des erreurs.

Travailler avec des API sécurisées

Lorsqu’on consomme des API REST, la gestion de l’authentification est primordiale. Elle garantit que seules les entités autorisées peuvent accéder aux ressources. Python, via requests, permet de gérer plusieurs types d’authentification. Voici les modèles les plus courants, du plus simple au plus avancé.

Authentification HTTP Basic

Le schéma Basic envoie un couple utilisateur:motdepasse encodé en Base64 dans un entête HTTP :

Authorization: Basic base64(utilisateur:motdepasse)

Python gère automatiquement cette conversion via le module requests.auth :

from requests.auth import HTTPBasicAuth
import requests
auth = HTTPBasicAuth("admin", "motdepasse")
response = requests.get("https://api.exemple.com/serveurs", auth=auth)

Cela génère automatiquement le header :

Authorization: Basic YWRtaW46bW90ZGVwYXNzZQ==

⚠️ Cette méthode doit toujours être utilisée avec HTTPS, car l’encodage Base64 n’est pas du chiffrement.

Authentification par clé API (API Key)

De nombreuses APIs utilisent une clé d’authentification unique, transmise de deux façons :

Dans les en-têtes HTTP

headers = {
"x-api-key": "sk_test_ABC123"
}
response = requests.get("https://api.exemple.com/instances", headers=headers)

En paramètre de requête

params = {
"api_key": "sk_test_ABC123"
}
response = requests.get("https://api.exemple.com/instances", params=params)

Ce type d’authentification est simple mais sensible à l’exposition de la clé. Elle donne un accès complet aux endpoints autorisés.

Jeton Bearer (OAuth2, JWT)

La méthode Bearer consiste à transmettre un jeton d’accès temporaire dans l’en-tête HTTP :

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

En Python :

headers = {
"Authorization": "Bearer VOTRE_JETON",
"Accept": "application/json"
}
response = requests.get("https://api.exemple.com/vms", headers=headers)

Ce jeton est souvent obtenu via un login initial ou une authentification OAuth2, et expire généralement après un certain temps.

OAuth2 — Jeton via identifiants client

De nombreuses APIs (GitLab, Azure, etc.) imposent un échange initial pour obtenir un jeton d’accès temporaire, en envoyant un client_id et un client_secret :

url = "https://auth.exemple.com/oauth/token"
data = {
"grant_type": "client_credentials",
"client_id": "votre_id",
"client_secret": "votre_secret"
}
response = requests.post(url, data=data)
access_token = response.json()["access_token"]

Puis utilisation du jeton :

headers = {"Authorization": f"Bearer {access_token}"}
requests.get("https://api.exemple.com/data", headers=headers)

5. Sessions persistantes avec requests.Session

Pour éviter de dupliquer les headers d’authentification sur plusieurs appels :

session = requests.Session()
session.headers.update({
"Authorization": "Bearer VOTRE_JETON",
"Accept": "application/json"
})
response = session.get("https://api.exemple.com/monitoring")

Cela améliore la lisibilité et la maintenabilité du code dans les scripts plus longs.

Bonnes pratiques pour sécuriser l’authentification API

Utiliser une authentification sécurisée dans vos scripts Python ne suffit pas : il faut également adopter des bonnes pratiques pour éviter les fuites d’informations sensibles, protéger vos infrastructures, et garantir la maintenabilité de vos scripts d’automatisation.

Ne jamais coder en dur une clé ou un mot de passe

Évitez d’insérer vos API keys, tokens, ou mots de passe directement dans le script. Exemple à éviter absolument :

# Mauvais exemple
headers = {"Authorization": "Bearer sk_live_tres_secret"}

En cas de fuite (GitHub, partage de fichier…), cela donne un accès direct à vos ressources.

Utiliser un fichier .env pour stocker les secrets

Créez un fichier .env :

Terminal window
API_KEY=sk_prod_xxxxxx
BEARER_TOKEN=eyJhbGciOiJIUzI1...

Ajoutez ensuite ce fichier à .gitignore :

Terminal window
.env

Dans votre script Python, chargez les variables avec python-dotenv :

Terminal window
pip install python-dotenv
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("API_KEY")
headers = {"x-api-key": api_key}

Chiffrer les échanges (HTTPS obligatoire)

Tous les appels API doivent être faits sur des URLs HTTPS. Le chiffrement TLS :

  • Protège les données en transit (auth, payload)
  • Évite les attaques de type man-in-the-middle

Stocker les logs d’erreurs sans exposer les secrets

Lorsque vous tracez des appels API échoués, n’incluez jamais les clés ou tokens dans les logs :

import logging
try:
response = requests.get("https://api.exemple.com/infra")
response.raise_for_status()
except requests.exceptions.RequestException as e:
logging.error(f"Erreur API : {e}")

Revoir et sécuriser les dépôts Git

  • Toujours ajouter .env à .gitignore
  • Scanner votre historique Git avec truffleHog ou gitleaks pour détecter les fuites
  • Utiliser GitHub Secrets, GitLab CI/CD Variables ou Vault pour injecter les valeurs dynamiquement

Contrôle de connaissances

Pourquoi ce contrôle ?

Cet contrôle va vous permettre de valider vos connaissances sur le sujet abordé dans le guide. Il comporte des QCM, des questions vrai/faux et des réponses ouvertes à un mot.

🕒 Le chronomètre commence dès que vous cliquez sur Démarrer le test. Vous devrez terminer l’examen avant la fin du temps imparti.

🎯 Pour réussir, vous devez obtenir au moins 80% de bonnes réponses.

💡 Je ne fournis pas directement les réponses aux questions. Cependant, si certaines sont complexes, des pistes d’explication pourront être proposées dans le guide ou après l’examen.

Bonne chance ! 🚀

Conclusion

Consommer des API REST en Python est une compétence indispensable pour automatiser et intégrer vos outils d’infrastructure. Grâce à la simplicité de requests, il est possible de piloter des services distants de manière fiable et sécurisée. En appliquant les bonnes pratiques d’authentification et de gestion des erreurs, vos scripts deviennent des briques robustes au cœur de vos workflows DevOps.