from typing import Dict from .clients.amadeus_client import AmadeusClient from .weather import geocode_city from .config import MAX_AIRPORT_KM def nearest_airports_for_city(city: str, max_km: int = MAX_AIRPORT_KM) -> Dict: """ Returns nearest airports to the given city (within max_km). Output: {"location": {...}, "airports": [airport_dicts_with__distance_km], "raw": raw_list} Raises on geocoding or network errors. """ loc = geocode_city(city) # {name, lat, lon, country} client = AmadeusClient() res = client.airports_nearby(lat=loc["lat"], lon=loc["lon"]) filtered = [] for a in res.get("data", []): dist = a.get("distance", {}) val = dist.get("value") unit = (dist.get("unit") or "").upper() if val is None: continue km = float(val) if unit == "KM" else float(val) * 1.60934 a["_distance_km"] = km if km <= max_km: filtered.append(a) return {"location": loc, "airports": filtered, "raw": res.get("data", [])} def assert_city_has_airport(city: str, max_km: int = MAX_AIRPORT_KM) -> Dict: """Validates a city has at least one airport within max_km. Raises RuntimeError otherwise.""" data = nearest_airports_for_city(city, max_km) if len(data["airports"]) == 0: raise RuntimeError(f"No airport found within {max_km} km of '{city}'. Please try a nearby larger city.") return data