# Appeler une API avec requests

curl et Bruno, c'est bien pour explorer. Mais pour automatiser, il faut appeler l'API depuis du code. Les exemples sont donnés en **Python**, avec la bibliothèque `requests`.

### Prérequis

Python 3 et la bibliothèque `requests` : `pip install requests`.

<p class="callout info">Votre clé d'API n'a rien à faire dans le code (ni dans git). Passez-la par une variable d'environnement : `export API_KEY=votre-cle`.</p>

### Lire une ressource

```python
import requests

BASE = "http://api-ritif.portlatch.com/v1"

res = requests.get(BASE + "/cocktails/3")
cocktail = res.json()
print(res.status_code, cocktail["name"])
```

### Paramètres de query

```python
res = requests.get(BASE + "/cocktails", params={"alcohol_free": "true", "per_page": 5})
```

### Envoyer du JSON avec un header

```python
import os

res = requests.post(
    BASE + "/orders",
    json={"cocktail_id": 3},
    headers={"X-API-Key": os.environ["API_KEY"]},
)
print(res.status_code, res.headers.get("Location"))
```

Avec `json=`, `requests` sérialise le body et ajoute le `Content-Type` tout seul.

### Le piège : les erreurs HTTP

<p class="callout warning">`requests` ne lève **pas** d'erreur sur un `404` ou un `500` : il ne le fait que si le réseau est coupé. Votre code continue donc tranquillement… avec une réponse d'erreur.</p>

```python
res = requests.get(BASE + "/cocktails/999")
res.raise_for_status()  # lève une exception si le code est 4xx ou 5xx
```

### En résumé

<table id="bkmrk-javascript-%28fetch%29py"><thead><tr><th></th><th>Python (`requests`)</th></tr></thead><tbody><tr><td>Code de statut</td><td>`res.status_code`</td></tr><tr><td>Succès (2xx) ?</td><td>`res.ok`</td></tr><tr><td>Header</td><td>`res.headers["Location"]`</td></tr><tr><td>Body JSON</td><td>`res.json()`</td></tr><tr><td>Envoyer du JSON</td><td>`json=...`</td></tr><tr><td>Lever une erreur</td><td>`res.raise_for_status()`</td></tr></tbody></table>