[ka2] fix connecteur c21_on: retry avec backoff dans _query (une réponse 200 non-JSONP transitoire — throttle Moxi/escalade Oxylabs — avortait tout le fetch ~45 min de l'Ontario)
1 changed file +22 −6
modified
immoka/connectors/c21_canada.py
+22 −6
@@ -24,6 +24,8 @@ import json | ||
| 24 | 24 | import re |
| 25 | 25 | import time |
| 26 | 26 | |
| 27 | +import requests | |
| 28 | + | |
| 27 | 29 | from .base import BaseConnector |
| 28 | 30 | from ..schema import PropertyListing |
| 29 | 31 | |
@@ -89,12 +91,26 @@ class _C21Province(BaseConnector): | ||
| 89 | 91 | params["pricemin"] = str(pricemin) |
| 90 | 92 | if pricemax is not None: |
| 91 | 93 | params["pricemax"] = str(pricemax) |
| 92 | − resp = self.get(API, params=params) | |
| 93 | − body = _CB_RE.sub("", resp.text.strip()) | |
| 94 | − d = json.loads(body) | |
| 95 | − if d.get("status") != "success": | |
| 96 | − raise RuntimeError(f"c21 API: {d.get('message', d.get('status'))}") | |
| 97 | − return d["data"] | |
| 94 | + # Un fetch provincial = des centaines de requêtes sur ~45 min (Ontario) : | |
| 95 | + # Moxi throttle parfois, ou l'escalade anti-bot renvoie un 200 au corps | |
| 96 | + # non-JSONP. Sans retry, UNE réponse pourrie avortait tout le sync | |
| 97 | + # (cause du stale c21_on 2026-08-29/30) → on retente avec backoff. | |
| 98 | + last_exc: Exception | None = None | |
| 99 | + for attempt in range(4): | |
| 100 | + if attempt: | |
| 101 | + time.sleep(min(5.0 * 2 ** (attempt - 1), 20.0)) | |
| 102 | + try: | |
| 103 | + resp = self.get(API, params=params) | |
| 104 | + body = _CB_RE.sub("", resp.text.strip()) | |
| 105 | + d = json.loads(body) | |
| 106 | + if d.get("status") != "success": | |
| 107 | + raise RuntimeError( | |
| 108 | + f"c21 API: {d.get('message', d.get('status'))}") | |
| 109 | + return d["data"] | |
| 110 | + except (json.JSONDecodeError, RuntimeError, | |
| 111 | + requests.RequestException) as exc: | |
| 112 | + last_exc = exc | |
| 113 | + raise last_exc # type: ignore[misc] | |
| 98 | 114 | |
| 99 | 115 | def _count(self, lo: int | None, hi: int | None, |
| 100 | 116 | location: str | None = None) -> int: |
| 101 | 117 | |