import httpx from fastapi import APIRouter, HTTPException, Query from app.config import settings from app.internal.logger import logger router = APIRouter(prefix="/places", tags=["places"]) PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/textsearch/json" DIRECTIONS_URL = "https://maps.googleapis.com/maps/api/directions/json" @router.get("/search") async def search_places(query: str = Query(...), near: str = Query("")): if not settings.google_maps_api_key: raise HTTPException(503, "Google Maps API not configured.") full_query = f"{query} {near}".strip() try: async with httpx.AsyncClient(timeout=10) as client: r = await client.get( PLACES_SEARCH_URL, params={"query": full_query, "key": settings.google_maps_api_key}, ) r.raise_for_status() data = r.json() except Exception as e: logger.error(f"Places search failed: {e}") raise HTTPException(502, "Places search failed.") return [ { "name": p.get("name"), "address": p.get("formatted_address"), "place_id": p.get("place_id"), "lat": p.get("geometry", {}).get("location", {}).get("lat"), "lng": p.get("geometry", {}).get("location", {}).get("lng"), "maps_link": f"https://www.google.com/maps/place/?q=place_id:{p.get('place_id')}", "rating": p.get("rating"), } for p in data.get("results", [])[:6] ] @router.get("/directions") async def get_directions( origin: str = Query(...), destination: str = Query(...), ): if not settings.google_maps_api_key: raise HTTPException(503, "Google Maps API not configured.") try: async with httpx.AsyncClient(timeout=10) as client: r = await client.get( DIRECTIONS_URL, params={ "origin": origin, "destination": destination, "mode": "driving", "key": settings.google_maps_api_key, }, ) r.raise_for_status() data = r.json() except Exception as e: logger.error(f"Directions failed: {e}") raise HTTPException(502, "Directions request failed.") routes = data.get("routes", []) if not routes: return {"duration_text": None, "duration_seconds": None, "distance_text": None} leg = routes[0]["legs"][0] return { "duration_text": leg["duration"]["text"], "duration_seconds": leg["duration"]["value"], "distance_text": leg["distance"]["text"], }