beach-app / app.py
sakthivel26's picture
Create app.py
f743115 verified
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"
"&current_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()