diff --git a/api/nominatim.py b/api/nominatim.py index 3e8ec370..a9b9c71f 100644 --- a/api/nominatim.py +++ b/api/nominatim.py @@ -11,14 +11,26 @@ SEARCH_URL = "https://nominatim.openstreetmap.org/search" -def nominatim_search(q: str, *, polygons: bool = False, limit: int = 5) -> list: +#: Result language when the caller gives none. Nominatim answers in the +#: place's local language when no Accept-Language reaches it (#420), and a +#: server-side request never carries the browser's. +DEFAULT_LANGUAGE = "en" + + +def nominatim_search(q: str, *, polygons: bool = False, limit: int = 5, + language: str = "") -> list: """One Nominatim search; raises on transport/HTTP errors. With ``polygons``, boundary geometry comes back pre-simplified so a whole country stays a few tens of KB.""" # Call-time import so tests patching core.ssrf.safe_get take effect. from core.ssrf import safe_get - params: dict = {"q": q, "format": "jsonv2", "limit": limit} + params: dict = { + "q": q, "format": "jsonv2", "limit": limit, + # Comma list or Accept-Language syntax; capped so a header can't + # bloat the URL. + "accept-language": (language or DEFAULT_LANGUAGE)[:100], + } if polygons: params |= {"polygon_geojson": 1, "polygon_threshold": 0.003} resp = safe_get( diff --git a/api/viewsets.py b/api/viewsets.py index cb5dd9b6..c0125920 100644 --- a/api/viewsets.py +++ b/api/viewsets.py @@ -2111,7 +2111,7 @@ def geocode(self, request): if not q: raise ValidationError({"q": "Type an address."}) try: - rows = nominatim_search(q) + rows = nominatim_search(q, language=request.META.get("HTTP_ACCEPT_LANGUAGE", "")) except Exception as exc: # noqa: BLE001 - surfaced, not raised return Response( {"detail": f"OpenStreetMap lookup failed: {exc}"}, @@ -8432,7 +8432,8 @@ def boundary_lookup(self, request): if not q: raise ValidationError({"q": "Type a place or postal code."}) try: - rows = nominatim_search(q, polygons=True) + rows = nominatim_search( + q, polygons=True, language=request.META.get("HTTP_ACCEPT_LANGUAGE", "")) except Exception as exc: # noqa: BLE001 - surfaced, not raised return Response( {"detail": f"OpenStreetMap lookup failed: {exc}"},