Shafaq25 commited on
Commit
c76c926
Β·
verified Β·
1 Parent(s): 039843c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -44
app.py CHANGED
@@ -2,13 +2,16 @@ import os
2
  import gradio as gr
3
  import requests
4
  from openai import OpenAI
 
5
 
6
- # API keys
7
  weather_api_key = os.getenv("openweather")
8
  openai_api_key = os.getenv("OPENAI_API_KEY")
9
  client = OpenAI(api_key=openai_api_key)
10
 
11
- # Fetch Weather
 
 
12
  def get_weather(city_name):
13
  if not city_name.strip():
14
  city_name = "Dubai"
@@ -16,7 +19,7 @@ def get_weather(city_name):
16
  url = f"https://api.openweathermap.org/data/2.5/weather?q={city_name}&appid={weather_api_key}&units=metric"
17
  data = requests.get(url).json()
18
 
19
- if data["cod"] == 200:
20
  rain = data.get("rain", {}).get("1h", 0)
21
  condition = data["weather"][0]["main"]
22
  emoji_map = {
@@ -38,13 +41,14 @@ def get_weather(city_name):
38
  "visibility": data.get("visibility", 10000) // 1000,
39
  "rain_chance": f"{rain} mm"
40
  }
41
- else:
42
- return None
43
- except:
44
  return None
45
 
46
 
47
- # Format Weather
 
 
48
  def format_weather_display(data):
49
  if not data:
50
  return "<div style='text-align:center; color: #e74c3c; font-size: 18px; padding: 40px;'>❌ City not found. Please try again.</div>"
@@ -96,7 +100,9 @@ def format_weather_display(data):
96
  """
97
 
98
 
99
- # Chatbot using OpenAI
 
 
100
  def travel_chat(msg, history):
101
  messages = [{"role": "system", "content": "You are a helpful travel assistant. Suggest tourist attractions, activities, and travel tips for any city."}]
102
  for h in history:
@@ -118,7 +124,9 @@ def travel_chat(msg, history):
118
  return history, history
119
 
120
 
121
- # Fetch attractions for city
 
 
122
  def get_attractions(city, country, temp, weather_desc):
123
  try:
124
  messages = [
@@ -139,19 +147,19 @@ def get_attractions(city, country, temp, weather_desc):
139
  )
140
 
141
  content = response.choices[0].message.content.strip()
142
-
143
  attractions = []
144
- for line in content.split('\n'):
145
  line = line.strip().rstrip(',')
146
- if line.startswith('(') and line.endswith(')'):
147
  try:
148
- attraction_tuple = eval(line)
149
  if isinstance(attraction_tuple, tuple) and len(attraction_tuple) == 2:
150
  attractions.append(attraction_tuple)
151
- except:
152
  continue
 
153
  return attractions if attractions else [("No attractions found", "Try another city.")]
154
- except:
155
  return [("Error", "Could not fetch attractions.")]
156
 
157
 
@@ -164,8 +172,9 @@ def format_attraction_card(name, details):
164
  """
165
 
166
 
 
167
  # CSS
168
- # CSS
169
  custom_css = """
170
  body, .gradio-container {
171
  background: linear-gradient(135deg, #f5f7fa 0%, #bbdefb 100%) !important;
@@ -176,7 +185,7 @@ body, .gradio-container {
176
  text-align: center;
177
  font-size: 2.8rem;
178
  font-weight: 800;
179
- margin: 20px 0 15px 0;
180
  color: #0d47a1;
181
  }
182
  .section-header {
@@ -185,17 +194,10 @@ body, .gradio-container {
185
  padding: 12px 20px;
186
  border-radius: 12px 12px 0 0;
187
  margin: 0;
188
- font-size: 1.2rem;
189
  font-weight: 600;
190
  text-align: center;
191
  }
192
- .section-subheading {
193
- text-align: center;
194
- font-size: 0.95rem;
195
- color: #444;
196
- margin: 10px 0 15px 0;
197
- font-style: italic;
198
- }
199
  .content-box {
200
  background-color: #ffffff;
201
  border-radius: 0 0 16px 16px;
@@ -236,27 +238,43 @@ body, .gradio-container {
236
  text-align: center;
237
  }
238
  .footer {
239
- background: linear-gradient(135deg, #0d47a1 0%, #002171 100%);
240
- color: white;
241
- padding: 20px;
242
  text-align: center;
243
- margin-top: 40px;
244
  font-size: 14px;
245
- border-radius: 12px;
 
 
246
  }
247
  """
248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  # UI
 
250
  def launch_ui():
251
- with gr.Blocks(css=custom_css, title="Travel Weather Guide") as demo:
252
- # HEADER
253
- gr.Markdown("<div id='main-title'>🌍 Travel Weather Guide</div>")
254
 
255
  with gr.Row(equal_height=True):
256
  # Weather section
257
  with gr.Column(scale=1):
258
  gr.Markdown("<div class='section-header'>🌀️ Weather Dashboard</div>")
259
- gr.Markdown("<div class='section-subheading'>Check current weather details</div>")
260
  with gr.Group(elem_classes="content-box"):
261
  city_input = gr.Textbox(label="πŸ™οΈ City Name", value="Dubai")
262
  update_btn = gr.Button("πŸ“ Get Weather Data")
@@ -264,8 +282,7 @@ def launch_ui():
264
 
265
  # Chatbot section
266
  with gr.Column(scale=1):
267
- gr.Markdown("<div class='section-header'>✈️ Travel Assistant</div>")
268
- gr.Markdown("<div class='section-subheading'>Ask for travel tips and suggestions</div>")
269
  with gr.Group(elem_classes="content-box"):
270
  chat = gr.Chatbot(height=350, type="messages")
271
  with gr.Row():
@@ -275,16 +292,8 @@ def launch_ui():
275
 
276
  # Attractions section
277
  gr.Markdown("<div class='section-header'>πŸ–οΈ Top Attractions You Can Visit</div>")
278
- gr.Markdown("<div class='section-subheading'>Plan your trip with these recommendations</div>")
279
  attractions_html = gr.HTML()
280
 
281
- # FOOTER
282
- gr.HTML("""
283
- <div class='footer'>
284
- Built with ❀️ | Powered by OpenWeather & OpenAI | © 2025 Travel Weather Guide
285
- </div>
286
- """)
287
-
288
  def update_all(city):
289
  return format_weather_display(get_weather(city)), generate_attraction_cards(city)
290
 
@@ -296,4 +305,10 @@ def launch_ui():
296
 
297
  demo.load(fn=lambda: update_all("Dubai"), inputs=None, outputs=[weather_html, attractions_html])
298
 
 
 
 
299
  demo.launch()
 
 
 
 
2
  import gradio as gr
3
  import requests
4
  from openai import OpenAI
5
+ import ast
6
 
7
+ # API Keys
8
  weather_api_key = os.getenv("openweather")
9
  openai_api_key = os.getenv("OPENAI_API_KEY")
10
  client = OpenAI(api_key=openai_api_key)
11
 
12
+ # -------------------------------
13
+ # Fetch Weather Data
14
+ # -------------------------------
15
  def get_weather(city_name):
16
  if not city_name.strip():
17
  city_name = "Dubai"
 
19
  url = f"https://api.openweathermap.org/data/2.5/weather?q={city_name}&appid={weather_api_key}&units=metric"
20
  data = requests.get(url).json()
21
 
22
+ if data.get("cod") == 200:
23
  rain = data.get("rain", {}).get("1h", 0)
24
  condition = data["weather"][0]["main"]
25
  emoji_map = {
 
41
  "visibility": data.get("visibility", 10000) // 1000,
42
  "rain_chance": f"{rain} mm"
43
  }
44
+ return None
45
+ except Exception:
 
46
  return None
47
 
48
 
49
+ # -------------------------------
50
+ # Weather Display HTML
51
+ # -------------------------------
52
  def format_weather_display(data):
53
  if not data:
54
  return "<div style='text-align:center; color: #e74c3c; font-size: 18px; padding: 40px;'>❌ City not found. Please try again.</div>"
 
100
  """
101
 
102
 
103
+ # -------------------------------
104
+ # Chatbot
105
+ # -------------------------------
106
  def travel_chat(msg, history):
107
  messages = [{"role": "system", "content": "You are a helpful travel assistant. Suggest tourist attractions, activities, and travel tips for any city."}]
108
  for h in history:
 
124
  return history, history
125
 
126
 
127
+ # -------------------------------
128
+ # Attractions
129
+ # -------------------------------
130
  def get_attractions(city, country, temp, weather_desc):
131
  try:
132
  messages = [
 
147
  )
148
 
149
  content = response.choices[0].message.content.strip()
 
150
  attractions = []
151
+ for line in content.splitlines():
152
  line = line.strip().rstrip(',')
153
+ if line.startswith("(") and line.endswith(")"):
154
  try:
155
+ attraction_tuple = ast.literal_eval(line)
156
  if isinstance(attraction_tuple, tuple) and len(attraction_tuple) == 2:
157
  attractions.append(attraction_tuple)
158
+ except Exception:
159
  continue
160
+
161
  return attractions if attractions else [("No attractions found", "Try another city.")]
162
+ except Exception:
163
  return [("Error", "Could not fetch attractions.")]
164
 
165
 
 
172
  """
173
 
174
 
175
+ # -------------------------------
176
  # CSS
177
+ # -------------------------------
178
  custom_css = """
179
  body, .gradio-container {
180
  background: linear-gradient(135deg, #f5f7fa 0%, #bbdefb 100%) !important;
 
185
  text-align: center;
186
  font-size: 2.8rem;
187
  font-weight: 800;
188
+ margin: 20px 0;
189
  color: #0d47a1;
190
  }
191
  .section-header {
 
194
  padding: 12px 20px;
195
  border-radius: 12px 12px 0 0;
196
  margin: 0;
197
+ font-size: 1.3rem;
198
  font-weight: 600;
199
  text-align: center;
200
  }
 
 
 
 
 
 
 
201
  .content-box {
202
  background-color: #ffffff;
203
  border-radius: 0 0 16px 16px;
 
238
  text-align: center;
239
  }
240
  .footer {
 
 
 
241
  text-align: center;
 
242
  font-size: 14px;
243
+ padding: 20px;
244
+ color: #555;
245
+ margin-top: 20px;
246
  }
247
  """
248
 
249
+ # -------------------------------
250
+ # Generate Attraction Cards
251
+ # -------------------------------
252
+ def generate_attraction_cards(city):
253
+ weather = get_weather(city)
254
+ if not weather:
255
+ return "<div style='padding:20px; color:red;'>⚠️ Couldn't fetch attractions due to missing weather data.</div>"
256
+
257
+ attractions = get_attractions(
258
+ city=weather["city"],
259
+ country=weather["country"],
260
+ temp=weather["temperature"],
261
+ weather_desc=weather["description"]
262
+ )
263
+ return "<div class='card-grid'>" + "".join(format_attraction_card(name, details) for name, details in attractions) + "</div>"
264
+
265
+
266
+ # -------------------------------
267
  # UI
268
+ # -------------------------------
269
  def launch_ui():
270
+ with gr.Blocks(css=custom_css, title="TripMate AI") as demo:
271
+ # Main Title
272
+ gr.Markdown("<div id='main-title'>🌍 TripMate AI</div>")
273
 
274
  with gr.Row(equal_height=True):
275
  # Weather section
276
  with gr.Column(scale=1):
277
  gr.Markdown("<div class='section-header'>🌀️ Weather Dashboard</div>")
 
278
  with gr.Group(elem_classes="content-box"):
279
  city_input = gr.Textbox(label="πŸ™οΈ City Name", value="Dubai")
280
  update_btn = gr.Button("πŸ“ Get Weather Data")
 
282
 
283
  # Chatbot section
284
  with gr.Column(scale=1):
285
+ gr.Markdown("<div class='section-header'>πŸ€– Travel Assistant</div>")
 
286
  with gr.Group(elem_classes="content-box"):
287
  chat = gr.Chatbot(height=350, type="messages")
288
  with gr.Row():
 
292
 
293
  # Attractions section
294
  gr.Markdown("<div class='section-header'>πŸ–οΈ Top Attractions You Can Visit</div>")
 
295
  attractions_html = gr.HTML()
296
 
 
 
 
 
 
 
 
297
  def update_all(city):
298
  return format_weather_display(get_weather(city)), generate_attraction_cards(city)
299
 
 
305
 
306
  demo.load(fn=lambda: update_all("Dubai"), inputs=None, outputs=[weather_html, attractions_html])
307
 
308
+ # Footer
309
+ gr.Markdown("<div class='footer'>Β© 2025 TripMate AI – Your AI-powered travel companion.</div>")
310
+
311
  demo.launch()
312
+
313
+
314
+ launch_ui()