Felhantering, retries och rate limits
Robust integration mot natomrade-API — vad du ska och inte ska göra.
HTTP-statuskoder
| Kod | Betydelse | Hur du ska reagera |
|---|---|---|
| 200 | OK | — |
| 400 | Ogiltig query | Fixa input, försök inte igen |
| 401 | Ingen / felaktig API-nyckel | Kontrollera X-API-Key-header |
| 403 | Kontot blockerat | Kontakta support |
| 404 | Resurs hittades inte (t.ex. postnr) | Returnera tomt till user |
| 429 | Rate-limited | Backoff enligt nedan |
| 500 | Serverfel | Retry med exponential backoff |
| 503 | Tjänsten otillgänglig | Retry efter Retry-After |
429-strukturen
{
"error": "rate_limited",
"scope": "per_minute", // per_minute | per_hour | per_day | per_ip_per_day | global_per_day
"limit": 30,
"throttle_minutes": 2, // bara om auto-throttle slog till
"throttle_level": 1,
"code": 429
}
Vid throttle_minutes > 0 är du auto-bannad i den tiden. Försök INTE igen direkt — det tripprar level 2.
Retry-strategi
import time, requests
def call_with_retry(url, headers, max_retries=5):
for attempt in range(max_retries):
r = requests.get(url, headers=headers, timeout=10)
if r.status_code == 200:
return r.json()
if r.status_code == 429:
data = r.json()
wait = data.get("throttle_minutes", 0) * 60
if wait == 0:
wait = min(2 ** attempt, 60) # exponential backoff
time.sleep(wait)
continue
if r.status_code in (500, 502, 503, 504):
time.sleep(min(2 ** attempt, 60))
continue
# 400/401/403/404 — försök inte igen
r.raise_for_status()
raise Exception("Max retries exceeded")
Anti-pattern
✗ Polla samma postnr varje sekund. Datat ändras inte. Cache i din ände, refresh max 1×/dag.
✗ Retry omedelbart vid 429. Auto-throttle tripprar och du blir bannad längre.
✗ Skicka många små anrop istället för batch. Batch-endpoints kommer — använd dem när de finns.
✗ Skicka känslig data i query-string. Adresser räknas som personuppgifter när de är kopplade till identitet. Anonymisera.
Caching
| Datatypen | Cache-livslängd | Varför |
|---|---|---|
| postnr → elområde/nätägare | 30 dagar | Stabil master-data |
| spotpris (current) | 15 min | Uppdateras 15-min-vis i eSett |
| spotpris (day-ahead) | 1 h efter publicering (~14:00) | Publiceras dagligen |
| nätägare-listan | 7 dagar | Ändras sällan |