Section 11.1.17 : APIs — Concepts et premier appel
🎯 Objectif pédagogique
Comprendre ce qu'est une API, comment elle fonctionne, et effectuer votre premier appel API avec Python. Vous serez capable d'expliquer REST, de lire une documentation API, et de consommer des données depuis un service externe.
L'API — Le langage universel des applications
Marc a compris le web. Il a compris le front et le back. Mais comment ces parties communiquent-elles entre elles ? Comment votre application météo récupère-t-elle les données ? Comment Uber affiche-t-il votre position en temps réel ? La réponse : les APIs.
API (Application Programming Interface) : un contrat de communication entre deux logiciels. "Si tu m'envoies cette requête avec ces paramètres, je te renvoie ces données dans ce format."
REST — Le standard des APIs web
REST (Representational State Transfer) est l'architecture dominante pour les APIs web :
| Principe | Signification |
|---|---|
| Ressources | Tout est une ressource identifiée par une URL |
| Méthodes HTTP | GET, POST, PUT, DELETE |
| Stateless | Chaque requête est indépendante |
| JSON | Format de données standard |
GET /api/users → Liste tous les utilisateurs
GET /api/users/42 → Détail de l'utilisateur 42
POST /api/users → Créer un utilisateur
PUT /api/users/42 → Modifier l'utilisateur 42
DELETE /api/users/42 → Supprimer l'utilisateur 42
JSON — Le format des données
\{
"id": 42,
"name": "Marc Dupont",
"email": "marc@email.com",
"skills": ["HTML", "CSS", "Python"],
"is_active": true,
"address": \{
"city": "Paris",
"country": "France"
\}
\}
JSON = JavaScript Object Notation. C'est LE format standard d'échange de données entre APIs. Presque identique aux dictionnaires Python.
Premier appel API avec Python
import requests
# GET — Récupérer des données
response = requests.get("https://jsonplaceholder.typicode.com/users")
print(f"Status : \{response.status_code\}") # 200
print(f"Type : \{response.headers['Content-Type']\}")
users = response.json() # Convertir JSON → liste Python
print(f"Nombre d'utilisateurs : \{len(users)\}")
for user in users[:3]:
print(f" - \{user['name']\} (\{user['email']\})")
Installer requests
pip install requests
Paramètres et headers
import requests
# Paramètres de requête (?key=value)
params = \{
"q": "Python developer",
"location": "Paris",
"limit": 10
\}
response = requests.get("https://api.example.com/jobs", params=params)
# → https://api.example.com/jobs?q=Python+developer&location=Paris&limit=10
# Headers (authentification, format)
headers = \{
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
\}
response = requests.get("https://api.example.com/data", headers=headers)
POST — Envoyer des données
import requests
# Créer une ressource
new_post = \{
"title": "Mon premier article",
"body": "Contenu de l'article...",
"userId": 1
\}
response = requests.post(
"https://jsonplaceholder.typicode.com/posts",
json=new_post # Envoie automatiquement en JSON
)
print(f"Status : \{response.status_code\}") # 201 (Created)
created = response.json()
print(f"ID créé : \{created['id']\}")
Gestion des erreurs API
import requests
def fetch_user(user_id):
url = f"https://jsonplaceholder.typicode.com/users/\{user_id\}"
try:
response = requests.get(url, timeout=5)
response.raise_for_status() # Lève une exception si 4xx/5xx
return response.json()
except requests.exceptions.Timeout:
print("⏱️ Le serveur ne répond pas")
except requests.exceptions.HTTPError as e:
print(f"❌ Erreur HTTP : \{e\}")
except requests.exceptions.ConnectionError:
print("🌐 Pas de connexion internet")
return None
# Utilisation
user = fetch_user(1)
if user:
print(f"Nom : \{user['name']\}")
Codes HTTP en pratique API
- →200 : OK — données reçues
- →201 : Created — ressource créée avec succès
- →400 : Bad Request — mauvais paramètres
- →401 : Unauthorized — clé API manquante/invalide
- →404 : Not Found — ressource inexistante
- →429 : Too Many Requests — rate limit atteint
- →500 : Server Error — bug côté API
🏋️ Exercice pratique (20 minutes)
import requests
# 1. Récupérer des posts
posts = requests.get("https://jsonplaceholder.typicode.com/posts").json()
print(f"Total posts : \{len(posts)\}")
# 2. Filtrer les posts d'un utilisateur
user_posts = [p for p in posts if p["userId"] == 1]
print(f"\nPosts de l'utilisateur 1 :")
for post in user_posts[:3]:
print(f" [\{post['id']\}] \{post['title'][:50]\}...")
# 3. Récupérer les commentaires d'un post
comments = requests.get(
"https://jsonplaceholder.typicode.com/posts/1/comments"
).json()
print(f"\nCommentaires du post 1 : \{len(comments)\}")
for comment in comments[:2]:
print(f" - \{comment['name']\} (\{comment['email']\})")
# 4. Créer un post
new_post = requests.post(
"https://jsonplaceholder.typicode.com/posts",
json=\{"title": "Mon post depuis Python", "body": "Hello API !", "userId": 1\}
).json()
print(f"\n✅ Post créé avec l'ID : \{new_post['id']\}")
Que signifie REST dans le contexte des APIs web ?
Quelle est la différence entre response.text et response.json() en Python requests ?
Un appel API retourne le code 429. Que devez-vous faire ?