Idempotence
Réessayer une écriture sans risque de la faire deux fois.
Une coupure réseau peut vous laisser sans savoir si votre requête a été traitée. Pour réessayer sans risque, envoyez avec chaque écriture (POST, PUT, PATCH, DELETE) un en-tête Idempotency-Key unique, par exemple un UUID :
curl -X POST https://api.corcelink.fr/v1/compute/vps/vps-7c2e4a91/reboot \
-H "Authorization: Bearer $CORCELINK_API_KEY" \
-H "Idempotency-Key: 4f9c2a3e-7b1d-4e0a-9c55-0d8f3b1a6e42"
| Situation | Réponse |
|---|---|
| Première requête avec cette clé | Traitée normalement |
| Même clé, même requête (même route, même corps) | La réponse d’origine, sans rien refaire, avec l’en-tête Idempotent-Replayed: true |
| Même clé, requête différente | 422 idempotency_key_reused |
| Même clé pendant que la première est en cours | 409 idempotency_in_progress : réessayez dans un instant |
La première a échoué par une erreur de notre côté (500, 503) |
La clé est libérée : la nouvelle tentative est traitée |
Une clé d’idempotence est gardée 24 heures, et propre à votre clé API. Générez-en une par opération voulue, et réutilisez-la seulement pour réessayer cette même opération.
import os, uuid, time, requests
key = str(uuid.uuid4()) # une clé pour ce redémarrage, réutilisée à chaque tentative
for attempt in range(4):
try:
r = requests.post("https://api.corcelink.fr/v1/compute/vps/vps-7c2e4a91/reboot",
headers={"Authorization": f"Bearer {os.environ['CORCELINK_API_KEY']}", "Idempotency-Key": key}, timeout=30)
if r.status_code < 500 and r.status_code not in (409, 429):
break
except requests.ConnectionError:
pass
time.sleep(2 ** attempt)
print(r.status_code, r.json())