Aller au contenu
Développement medium

Appeler une API REST en Python avec requests (GET, POST)

16 min de lecture

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 une API REST : ressources, endpoints, méthodes HTTP, codes de statut
  • Installer requests et lire vos secrets depuis un fichier .env
  • Appeler une API avec GET, POST, PUT, PATCH et DELETE
  • Gérer les erreurs avec raise_for_status() et un timeout systématique
  • Authentifier vos appels (Basic, clé API, jeton Bearer, OAuth2, Session)
  • Sécuriser : ne jamais coder un secret en dur, exiger HTTPS et ne jamais désactiver la vérification TLS

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.

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

Fenêtre de terminal
https://api.mon-cloud.fr/v1/servers

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

Chaque opération est liée à une méthode HTTP spécifique, qui décrit l'intention de l'appel :

  • 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.

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"
}

À 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

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

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éez un environnement virtuel avec venv pour isoler vos dépendances :

Fenêtre de terminal
python -m venv venv
source venv/bin/activate

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 :

Fenêtre de terminal
pip install requests

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

Organisez vos scripts avec une structure modulaire, séparant le point d'entrée des fonctions réutilisables :

Fenêtre de terminal
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

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

Fenêtre de terminal
API_KEY=sk_test_abc123
BASE_URL=https://api.mon-cloud.fr

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

Fenêtre de terminal
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.

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.

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
}

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
}

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
}

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
}

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.

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.

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

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: # True si le code est dans la plage 2xx
donnees = response.json()

response.ok vaut True si le code de statut est dans la plage 2xx.

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

try:
response = requests.get("https://api.mon-cloud.fr/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.

Fenêtre de terminal
Erreur HTTP : 410 Client Error: Gone for url: https://api.mon-cloud.fr/data

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.

Fenêtre de terminal
Erreur de connexion

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

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

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

Dans un script d’automatisation, loguez les erreurs dans un fichier au lieu de simplement les afficher :

import logging
logging.basicConfig(filename='api.log', level=logging.ERROR)
try:
r = requests.get("https://api.mon-cloud.fr/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.

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é.

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 Base64 via le module requests.auth :

from requests.auth import HTTPBasicAuth
import requests
auth = HTTPBasicAuth("admin", "motdepasse")
response = requests.get("https://api.mon-cloud.fr/serveurs", auth=auth)

Cela génère automatiquement le header :

Authorization: Basic YWRtaW46bW90ZGVwYXNzZQ==

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

headers = {
"x-api-key": "sk_test_ABC123"
}
response = requests.get("https://api.mon-cloud.fr/instances", headers=headers)
params = {
"api_key": "sk_test_ABC123"
}
response = requests.get("https://api.mon-cloud.fr/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.

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.mon-cloud.fr/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.

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.mon-cloud.fr/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.mon-cloud.fr/data", headers=headers)

Pour éviter de dupliquer les headers d’authentification sur plusieurs appels, réutilisez un objet Session :

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

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

Bonnes pratiques pour sécuriser l’authentification API

Section intitulée « 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

Section intitulée « 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.

Créez un fichier .env :

Fenêtre de terminal
API_KEY=sk_prod_xxxxxx
BEARER_TOKEN=eyJhbGciOiJIUzI1...

Ajoutez ensuite ce fichier à .gitignore :

Fenêtre de terminal
.env

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

Fenêtre de terminal
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}

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

Par défaut, requests vérifie le certificat TLS du serveur : c'est ce qui garantit que vous parlez bien au vrai serveur et non à un attaquant. Désactiver cette vérification avec verify=False rouvre grand la porte aux attaques man-in-the-middle, même en HTTPS. À proscrire :

# À NE JAMAIS FAIRE en production
requests.get("https://api.mon-cloud.fr/data", verify=False)

Si vous devez joindre une API interne avec une autorité de certification (CA) d'entreprise, ne désactivez pas la vérification : pointez requests vers le certificat de la CA :

requests.get("https://api.interne/data", verify="/etc/ssl/certs/ca-entreprise.pem")

Stocker les logs d’erreurs sans exposer les secrets

Section intitulée « 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.mon-cloud.fr/infra")
response.raise_for_status()
except requests.exceptions.RequestException as e:
logging.error(f"Erreur API : {e}")
  • 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

Validez vos connaissances avec ce quiz interactif

6 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • requests.get/post/put/patch/delete couvrent les cinq méthodes HTTP ; response.json() décode la réponse JSON.
  • Vérifiez toujours le résultat : response.raise_for_status() lève une exception sur un code d'erreur, à envelopper dans un try/except.
  • Un timeout sur chaque requête évite qu'un serveur lent ne bloque votre script indéfiniment.
  • requests.Session réutilise les en-têtes d'authentification sur plusieurs appels.
  • Secrets : jamais en dur, chargez-les depuis un .env (via python-dotenv) ajouté au .gitignore.
  • TLS : exigez HTTPS et ne désactivez jamais verify (verify=False rouvre la porte au man-in-the-middle) ; pour une CA interne, verify="/chemin/ca.pem".

Les réponses courtes ci-dessous couvrent les questions les plus recherchées sur requests. Chaque exemple est autonome et testé sur Python 3.12.

  • FastAPI : passer de la consommation à la création de vos propres API REST.
  • Les API REST : approfondir les concepts REST, ressources, verbes et statuts.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn