sakthivel26 commited on
Commit
f743115
Β·
verified Β·
1 Parent(s): ac77d64

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +182 -0
app.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ import gradio as gr
4
+ from dotenv import load_dotenv
5
+ from bs4 import BeautifulSoup
6
+
7
+ # ---------------------------------------------
8
+ # Load environment variables
9
+ # ---------------------------------------------
10
+ load_dotenv()
11
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
12
+
13
+ # ---------------------------------------------
14
+ # Static coordinates
15
+ # ---------------------------------------------
16
+ BEACH_COORDS = {
17
+ "marina beach": (13.0500, 80.2824),
18
+ "kovalam beach": (8.4000, 76.9780),
19
+ "goa beach": (15.2993, 74.1240),
20
+ "puri beach": (19.7983, 85.8245)
21
+ }
22
+
23
+ # ---------------------------------------------
24
+ # Geocoding
25
+ # ---------------------------------------------
26
+ def get_coordinates(beach):
27
+ try:
28
+ r = requests.get(
29
+ "https://nominatim.openstreetmap.org/search",
30
+ params={"q": f"{beach}, India", "format": "json", "limit": 1},
31
+ headers={"User-Agent": "BeachSafetyBot/1.0"},
32
+ timeout=10
33
+ ).json()
34
+ if r:
35
+ return float(r[0]["lat"]), float(r[0]["lon"])
36
+ except:
37
+ pass
38
+ return None, None
39
+
40
+ # ---------------------------------------------
41
+ # Weather
42
+ # ---------------------------------------------
43
+ def get_weather(lat, lon):
44
+ try:
45
+ d = requests.get(
46
+ f"https://api.open-meteo.com/v1/forecast"
47
+ f"?latitude={lat}&longitude={lon}"
48
+ "&daily=temperature_2m_max,temperature_2m_min"
49
+ "&current_weather=true&timezone=auto",
50
+ timeout=10
51
+ ).json()
52
+
53
+ return {
54
+ "temp": d["current_weather"]["temperature"],
55
+ "wind": d["current_weather"]["windspeed"],
56
+ "min": d["daily"]["temperature_2m_min"][0],
57
+ "max": d["daily"]["temperature_2m_max"][0]
58
+ }
59
+ except:
60
+ return {"temp": "N/A", "wind": "N/A", "min": "N/A", "max": "N/A"}
61
+
62
+ # ---------------------------------------------
63
+ # INCOIS alert
64
+ # ---------------------------------------------
65
+ def has_alert():
66
+ try:
67
+ html = requests.get(
68
+ "https://incois.gov.in/portal/tsunami.jsp",
69
+ timeout=10
70
+ ).text
71
+ return "WARNING" in html.upper()
72
+ except:
73
+ return False
74
+
75
+ # ---------------------------------------------
76
+ # Safety logic
77
+ # ---------------------------------------------
78
+ def evaluate(wind, alert, beach):
79
+ if alert:
80
+ return "NOT SUITABLE", "πŸ”΄ RED"
81
+ try:
82
+ wind = float(wind)
83
+ except:
84
+ wind = 0
85
+ if wind > 12 or "marina" in beach:
86
+ return "CAUTION", "🟑 YELLOW"
87
+ return "SUITABLE", "🟒 GREEN"
88
+
89
+ # ---------------------------------------------
90
+ # Wikipedia crawl
91
+ # ---------------------------------------------
92
+ def crawl_beach_details(beach):
93
+ details = {
94
+ "famous_for": "Scenic coastal destination",
95
+ "hotspots": ["Local shoreline"],
96
+ "safety_rules": ["Follow local advisories"],
97
+ "best_time": "Morning and evening"
98
+ }
99
+ try:
100
+ r = requests.get(
101
+ f"https://en.wikipedia.org/wiki/{beach.replace(' ', '_')}",
102
+ timeout=10
103
+ )
104
+ soup = BeautifulSoup(r.text, "html.parser")
105
+ p = soup.select("p")[:3]
106
+ if p:
107
+ details["famous_for"] = p[0].get_text().split(".")[0]
108
+ except:
109
+ pass
110
+ return details
111
+
112
+ # ---------------------------------------------
113
+ # Groq AI
114
+ # ---------------------------------------------
115
+ def groq_rewrite(prompt):
116
+ if not GROQ_API_KEY:
117
+ return None
118
+ try:
119
+ r = requests.post(
120
+ "https://api.groq.com/openai/v1/chat/completions",
121
+ headers={
122
+ "Authorization": f"Bearer {GROQ_API_KEY}",
123
+ "Content-Type": "application/json"
124
+ },
125
+ json={
126
+ "model": "llama-3.3-70b-versatile",
127
+ "messages": [{"role": "user", "content": prompt}],
128
+ "max_tokens": 400
129
+ },
130
+ timeout=20
131
+ )
132
+ return r.json()["choices"][0]["message"]["content"]
133
+ except:
134
+ return None
135
+
136
+ # ---------------------------------------------
137
+ # MAIN FUNCTION (Gradio)
138
+ # ---------------------------------------------
139
+ def beach_safety(question):
140
+ msg = question.lower().strip()
141
+ beach = msg if "beach" in msg else f"{msg} beach"
142
+
143
+ lat, lon = BEACH_COORDS.get(beach, get_coordinates(beach))
144
+ if not lat:
145
+ return "❌ Unable to locate this beach in India."
146
+
147
+ weather = get_weather(lat, lon)
148
+ status, color = evaluate(weather["wind"], has_alert(), beach)
149
+ details = crawl_beach_details(beach)
150
+
151
+ response = f"""
152
+ πŸ–οΈ **{beach.title()}**
153
+
154
+ **Status:** {status} ({color})
155
+
156
+ 🌑️ Temp: {weather['temp']}°C
157
+ πŸ’¨ Wind: {weather['wind']} km/h
158
+
159
+ πŸ“ **Famous For:**
160
+ {details['famous_for']}
161
+
162
+ πŸ• **Best Time:** {details['best_time']}
163
+ """
164
+
165
+ ai = groq_rewrite(response)
166
+ return ai if ai else response
167
+
168
+ # ---------------------------------------------
169
+ # Gradio UI
170
+ # ---------------------------------------------
171
+ demo = gr.Interface(
172
+ fn=beach_safety,
173
+ inputs=gr.Textbox(
174
+ label="Ask about an Indian beach",
175
+ placeholder="Is Marina Beach safe today?"
176
+ ),
177
+ outputs=gr.Markdown(),
178
+ title="πŸ–οΈ Beach Safety Assistant",
179
+ description="Real-time beach safety, weather & advisories for Indian beaches"
180
+ )
181
+
182
+ demo.launch()