Python 67%
TypeScript 18.2%
CSS 14.4%
1# -----------------------------------------------------------------------------2# Immo-Ka — Agrégateur de maisons à vendre (province de Québec)3# Auteur : Simon-Pierre Boucher — contact@spboucher.ai4# mortgage/providers/bank_of_canada.py : Banque du Canada — API Valet5# (officielle, publique, JSON). Séries de référence : taux hypothécaire6# conventionnel affiché 1/3/5 ans, taux directeur, rendement obligataire7# 5 ans. purpose="unknown" : séries de RÉFÉRENCE, exclues du comparateur8# de prêteurs (la BdC ne prête pas aux particuliers).9# -----------------------------------------------------------------------------10from __future__ import annotations1112from .base import RateProvider1314SERIES_URL = ("https://www.bankofcanada.ca/valet/observations/"15 "V80691333,V80691334,V80691335,V39079,BD.CDN.5YR.DQ.YLD/"16 "json?recent=10")1718# série -> (terme mois, nom de produit)19MORTGAGE_SERIES = {20 "V80691333": (12, "Taux hypothécaire conventionnel affiché — 1 an"),21 "V80691334": (36, "Taux hypothécaire conventionnel affiché — 3 ans"),22 "V80691335": (60, "Taux hypothécaire conventionnel affiché — 5 ans"),23}24CONTEXT_SERIES = {25 "V39079": "Taux cible du financement à un jour",26 "BD.CDN.5YR.DQ.YLD": "Rendement obligataire 5 ans — Gouvernement du Canada",27}282930class BankOfCanadaProvider(RateProvider):31 provider_id = "bank_of_canada"32 institution = "Banque du Canada"33 source_url = "https://www.bankofcanada.ca/rates/interest-rates/"34 request_delay = 0.53536 def fetch(self) -> list[dict]:37 return self.parse(self.get(SERIES_URL).text)3839 def parse(self, payload: str) -> list[dict]:40 import json41 data = json.loads(payload)42 observations = data.get("observations") or []43 # Séries à fréquences mélangées : garder la DERNIÈRE valeur par série.44 latest: dict[str, tuple[str, float]] = {}45 for obs in observations:46 d = obs.get("d", "")47 for sid, cell in obs.items():48 if sid == "d" or not isinstance(cell, dict):49 continue50 v = cell.get("v")51 if v in (None, ""):52 continue53 try:54 latest[sid] = (d, float(v))55 except ValueError:56 continue57 out: list[dict] = []58 for sid, (term, name) in MORTGAGE_SERIES.items():59 if sid not in latest:60 continue61 d, v = latest[sid]62 out.append(self.make_product(63 rate=v, rate_type="fixed", term_months=term, kind="posted",64 product_name=name, purpose="unknown",65 conditions=f"Série Valet {sid} — observation du {d} "66 "(moyenne hebdomadaire des taux affichés)",67 raw={"series": sid, "date": d, "value": v}))68 for sid, name in CONTEXT_SERIES.items():69 if sid not in latest:70 continue71 d, v = latest[sid]72 out.append(self.make_product(73 rate=v, rate_type="other", term_months=12, kind="posted",74 product_name=name, purpose="unknown",75 conditions=f"Série Valet {sid} — observation du {d}",76 raw={"series": sid, "date": d, "value": v}))77 return out78