Géocoder des adresses en Python avec pandas
Ce tutoriel géocode un DataFrame d'adresses avec l'API par lot d'Addrova, examine les lignes dont le service n'est pas sûr, et répare leurs fautes. Il utilise requests et pandas. Un SDK Python dédié est prévu ; voir la page SDK. [À VÉRIFIER : SDK non disponible ; ce tutoriel utilise l'API HTTP.]
L'URL de base https://api.addrova.eu n'est pas encore en ligne. Tout ce qui suit suit la spécification de l'API.
1. Préparer le fichier
import io
import os
import time
import pandas as pd
import requests
BASE = "https://api.addrova.eu"
HEADERS = {"X-API-Key": os.environ["ADDROVA_API_KEY"]}
df = pd.read_csv("clients.csv") # une colonne "adresse" avec l'adresse complète
print(len(df), "lignes")
Le point d'accès par lot accepte un CSV avec ligne d'en-tête. Les limites dépendent de l'offre : le catalogue donne 100 000 lignes par lot sur Starter. [À VÉRIFIER : limite par offre, voir /fr/pricing]
2. Envoyer, attendre, télécharger
buf = io.StringIO()
df[["adresse"]].to_csv(buf, index=False)
job = requests.post(
f"{BASE}/v1/batch",
headers=HEADERS,
files={"file": ("adresses.csv", buf.getvalue(), "text/csv")},
data={"address_column": "adresse", "country": "FR"},
timeout=60,
).json()
while job["status"] in ("queued", "running"):
time.sleep(2)
job = requests.get(f"{BASE}/v1/batch/{job['id']}", headers=HEADERS, timeout=10).json()
result_csv = requests.get(f"{BASE}/v1/batch/{job['id']}/result", headers=HEADERS, timeout=120).text
requests.delete(f"{BASE}/v1/batch/{job['id']}", headers=HEADERS, timeout=10) # purge immédiate
corps = "\n".join(l for l in result_csv.splitlines() if not l.startswith("#")) # retire la ligne de commentaire d'attribution
res = pd.read_csv(io.StringIO(corps))
Le résultat conserve vos colonnes et ajoute addrova_label, addrova_lat, addrova_lon, addrova_precision, addrova_confidence, addrova_confidence_level, addrova_sources et addrova_status. L'attribution est une ligne de commentaire finale, que le code ci-dessus retire avant de lire le tableau ; conservez-la avec vos données. Supprimer le job juste après le téléchargement est permis par l'API et ne laisse rien côté service (affirmation ZL-22 sur la page conformité).
3. Lire les statuts
print(res["addrova_status"].value_counts())
matched est une correspondance fiable, uncertain un meilleur candidat de faible confiance, not_found n'a aucun candidat, invalid une adresse vide ou rejetée.
4. Réparer les lignes incertaines
a_voir = res[res["addrova_status"].isin(["uncertain", "not_found"])]
def reparer(adresse, pays="FR"):
return requests.post(
f"{BASE}/v1/repair",
headers=HEADERS,
json={"address": adresse, "country": pays},
timeout=10,
).json()
corrigees = a_voir["adresse"].map(reparer)
res.loc[a_voir.index, "repair_status"] = corrigees.map(lambda r: r["status"])
res.loc[a_voir.index, "repair_confidence"] = corrigees.map(lambda r: r.get("confidence"))
res.loc[a_voir.index, "repaired_label"] = corrigees.map(lambda r: (r.get("result") or {}).get("label"))
Chaque réparation renvoie un status (unchanged, repaired, unrepairable), le result corrigé, une confidence et la liste des changes avec leur motif (abbreviation, typo, missing…). La réparation n'est facturée qu'en cas de succès. Relisez à la main tout ce qui a une confiance faible.
5. Conserver les résultats
res.to_csv("clients_geocodes.csv", index=False)
Vous pouvez stocker les résultats sans limite de durée. Conservez l'attribution qui les accompagne.
Conseils
- Géocodez d'abord un échantillon de 500 lignes et relisez les
uncertain. - Gardez code postal et ville dans des colonnes séparées si vous les avez, et passez-les avec l'option
columnsdu point d'accès par lot. - Gérez les réponses
429: l'en-têteRetry-Afterindique combien de temps attendre.