| from dotenv import load_dotenv |
| import os |
| import googlemaps |
| import re |
| import gradio as gr |
| from datetime import datetime |
|
|
| |
| dotenv_path = os.getenv('DOTENV_PATH', None) |
| if dotenv_path: |
| load_dotenv(dotenv_path) |
| else: |
| load_dotenv() |
|
|
| api_key = os.getenv("GOOGLE_API_KEY") |
| if not api_key: |
| raise EnvironmentError("GOOGLE_API_KEY not found in environment variables.") |
|
|
| gmaps = googlemaps.Client(key=api_key) |
|
|
|
|
| def get_places(trip_type: str, location: str) -> list[str]: |
| """ |
| Fetches up to 5 popular tourist attractions matching the trip_type in the given location. |
| """ |
| query = f"{trip_type} places in {location}" |
| results = gmaps.places(query=query, type="tourist_attraction") |
| places = results.get("results", [])[:5] |
| return [place.get("name") for place in places] |
|
|
|
|
| def get_restaurants(location: str, prefs: str) -> list[str]: |
| """ |
| Fetches up to 3 restaurants near the given location matching the user preferences. |
| """ |
| query = f"{prefs} restaurants near {location}" |
| results = gmaps.places(query=query, type="restaurant") |
| restaurants = results.get("results", [])[:3] |
| return [r.get("name") for r in restaurants] |
|
|
|
|
| def get_directions( |
| source: str, |
| destination: str, |
| mode: str, |
| departure_time: str, |
| waypoints: str = "" |
| ) -> str: |
| """ |
| Returns a Markdown-formatted string with step-by-step directions and a static map URL. |
| |
| Args: |
| source: Starting address or place name. |
| destination: Ending address or place name. |
| mode: Transport mode: driving, walking, bicycling, or transit. |
| departure_time: Trip start time in "YYYY-MM-DD HH:MM" format. |
| waypoints: Optional comma-separated list of waypoints. |
| |
| Returns: |
| A single Markdown string summarizing the route or an error message. |
| """ |
| |
| try: |
| dt = datetime.strptime(departure_time.strip(), "%Y-%m-%d %H:%M") |
| except ValueError: |
| return ( |
| "**⚠️ Invalid time format.** Please enter departure time as YYYY-MM-DD HH:MM." |
| ) |
|
|
| |
| wp_list = [w.strip() for w in waypoints.split(",")] if waypoints else None |
|
|
| |
| directions = gmaps.directions( |
| origin=source, |
| destination=destination, |
| mode=mode.lower(), |
| departure_time=dt, |
| waypoints=wp_list, |
| optimize_waypoints=False, |
| ) |
|
|
| if not directions: |
| return "**No route found.**" |
|
|
| |
| route = directions[0] |
| leg = route["legs"][0] |
|
|
| |
| summary = f"**Trip from '{leg['start_address']}' to '{leg['end_address']}'**\n" |
| summary += f"- Total distance: {leg['distance']['text']}\n" |
| summary += f"- Estimated duration: {leg['duration']['text']}\n\n" |
| summary += "### Step-by-Step Directions:\n" |
|
|
| for i, step in enumerate(leg["steps"], start=1): |
| travel_mode = step.get("travel_mode", "").upper() |
| if travel_mode == "TRANSIT": |
| details = step.get("transit_details", {}) |
| line = details.get("line", {}) |
| vehicle = line.get("vehicle", {}).get("type", "Transit") |
| line_name = line.get("short_name") or line.get("name", "") |
| dep = details.get("departure_stop", {}).get("name", "") |
| arr = details.get("arrival_stop", {}).get("name", "") |
| stops = details.get("num_stops", "") |
| instr = f"Take {vehicle} {line_name} from {dep} to {arr} ({stops} stops)" |
| dist = step.get("distance", {}).get("text", "") |
| else: |
| raw = step.get("html_instructions", "") |
| instr = re.sub(r"<[^>]+>", "", raw) |
| dist = step.get("distance", {}).get("text", "") |
|
|
| summary += f"{i}. {instr} ({dist})\n" |
|
|
| |
| poly = route.get("overview_polyline", {}).get("points") |
| if poly: |
| static_map_url = ( |
| "https://maps.googleapis.com/maps/api/staticmap" |
| f"?size=600x400&path=enc:{poly}&key={api_key}" |
| ) |
| summary += "\n---\n" |
| summary += ("Here’s a **static map snapshot** of this route:\n" + static_map_url) |
|
|
| return summary |
|
|
|
|
| |
| demo = gr.Interface( |
| fn=get_directions, |
| inputs=[ |
| gr.Textbox(label="Source Location", placeholder="e.g. New York City"), |
| gr.Textbox(label="Destination Location", placeholder="e.g. Los Angeles"), |
| gr.Radio( |
| ["driving", "walking", "bicycling", "transit"], |
| label="Travel Mode", |
| value="driving" |
| ), |
| gr.Textbox( |
| label="Departure Time (YYYY-MM-DD HH:MM)", |
| placeholder="e.g. 2025-06-08 14:30" |
| ), |
| gr.Textbox( |
| label="Waypoints (optional, comma-separated)", |
| placeholder="e.g. museum, coffee shop" |
| ), |
| ], |
| outputs=gr.Markdown(label="Directions Summary"), |
| title="Google Maps Directions", |
| description="Get step-by-step directions between two locations using the Google Maps API." |
| ) |
|
|
|
|
| demo.launch(mcp_server=True, share=True) |
|
|