import os import requests import gradio as gr from dotenv import load_dotenv from bs4 import BeautifulSoup # --------------------------------------------- # Load environment variables # --------------------------------------------- load_dotenv() GROQ_API_KEY = os.getenv("GROQ_API_KEY") # --------------------------------------------- # Static coordinates # --------------------------------------------- BEACH_COORDS = { "marina beach": (13.0500, 80.2824), "kovalam beach": (8.4000, 76.9780), "goa beach": (15.2993, 74.1240), "puri beach": (19.7983, 85.8245) } # --------------------------------------------- # Geocoding # --------------------------------------------- def get_coordinates(beach): try: r = requests.get( "https://nominatim.openstreetmap.org/search", params={"q": f"{beach}, India", "format": "json", "limit": 1}, headers={"User-Agent": "BeachSafetyBot/1.0"}, timeout=10 ).json() if r: return float(r[0]["lat"]), float(r[0]["lon"]) except: pass return None, None # --------------------------------------------- # Weather # --------------------------------------------- def get_weather(lat, lon): try: d = requests.get( f"https://api.open-meteo.com/v1/forecast" f"?latitude={lat}&longitude={lon}" "&daily=temperature_2m_max,temperature_2m_min" "¤t_weather=true&timezone=auto", timeout=10 ).json() return { "temp": d["current_weather"]["temperature"], "wind": d["current_weather"]["windspeed"], "min": d["daily"]["temperature_2m_min"][0], "max": d["daily"]["temperature_2m_max"][0] } except: return {"temp": "N/A", "wind": "N/A", "min": "N/A", "max": "N/A"} # --------------------------------------------- # INCOIS alert # --------------------------------------------- def has_alert(): try: html = requests.get( "https://incois.gov.in/portal/tsunami.jsp", timeout=10 ).text return "WARNING" in html.upper() except: return False # --------------------------------------------- # Safety logic # --------------------------------------------- def evaluate(wind, alert, beach): if alert: return "NOT SUITABLE", "🔴 RED" try: wind = float(wind) except: wind = 0 if wind > 12 or "marina" in beach: return "CAUTION", "🟡 YELLOW" return "SUITABLE", "🟢 GREEN" # --------------------------------------------- # Wikipedia crawl # --------------------------------------------- def crawl_beach_details(beach): details = { "famous_for": "Scenic coastal destination", "hotspots": ["Local shoreline"], "safety_rules": ["Follow local advisories"], "best_time": "Morning and evening" } try: r = requests.get( f"https://en.wikipedia.org/wiki/{beach.replace(' ', '_')}", timeout=10 ) soup = BeautifulSoup(r.text, "html.parser") p = soup.select("p")[:3] if p: details["famous_for"] = p[0].get_text().split(".")[0] except: pass return details # --------------------------------------------- # Groq AI # --------------------------------------------- def groq_rewrite(prompt): if not GROQ_API_KEY: return None try: r = requests.post( "https://api.groq.com/openai/v1/chat/completions", headers={ "Authorization": f"Bearer {GROQ_API_KEY}", "Content-Type": "application/json" }, json={ "model": "llama-3.3-70b-versatile", "messages": [{"role": "user", "content": prompt}], "max_tokens": 400 }, timeout=20 ) return r.json()["choices"][0]["message"]["content"] except: return None # --------------------------------------------- # MAIN FUNCTION (Gradio) # --------------------------------------------- def beach_safety(question): msg = question.lower().strip() beach = msg if "beach" in msg else f"{msg} beach" lat, lon = BEACH_COORDS.get(beach, get_coordinates(beach)) if not lat: return "❌ Unable to locate this beach in India." weather = get_weather(lat, lon) status, color = evaluate(weather["wind"], has_alert(), beach) details = crawl_beach_details(beach) response = f""" 🏖️ **{beach.title()}** **Status:** {status} ({color}) 🌡️ Temp: {weather['temp']}°C 💨 Wind: {weather['wind']} km/h 📍 **Famous For:** {details['famous_for']} 🕐 **Best Time:** {details['best_time']} """ ai = groq_rewrite(response) return ai if ai else response # --------------------------------------------- # Gradio UI # --------------------------------------------- demo = gr.Interface( fn=beach_safety, inputs=gr.Textbox( label="Ask about an Indian beach", placeholder="Is Marina Beach safe today?" ), outputs=gr.Markdown(), title="🏖️ Beach Safety Assistant", description="Real-time beach safety, weather & advisories for Indian beaches" ) demo.launch()