krishbaresha commited on
Commit
3199df3
·
verified ·
1 Parent(s): 74c1fcb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -54
app.py CHANGED
@@ -1,75 +1,106 @@
1
  import streamlit as st
2
- import streamlit.components.v1 as components
3
  import os
4
  import requests
 
5
 
6
- # 1. Page Config
7
  st.set_page_config(page_title="SkyCast Pro", page_icon="☁️", layout="centered")
8
 
9
- # 2. Path Settings
10
- parent_dir = os.path.dirname(os.path.abspath(__file__))
11
- # Directly pointing to your index.html
12
- html_path = os.path.join(parent_dir, "frontend", "dist", "index.html")
13
-
14
- # 3. Secure API Key
15
- API_KEY = os.environ.get('Api_key')
16
-
17
- # 4. Custom Styling for Streamlit UI
18
  st.markdown("""
19
  <style>
20
  .stApp { background-color: #0f172a; }
21
- h1 { color: white !important; text-align: center; font-weight: 200; letter-spacing: 5px; }
22
- .stTextInput>div>div>input {
23
- background-color: rgba(255,255,255,0.05) !important;
24
- color: white !important;
25
- border-radius: 10px !important;
 
 
 
 
 
26
  }
 
 
 
 
 
27
  </style>
28
  """, unsafe_allow_html=True)
29
 
30
  st.title("SKYCAST PRO")
31
 
32
- # 5. API Logic
33
- def get_weather(city):
34
- if not API_KEY: return None
35
- url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric"
36
- try:
37
- r = requests.get(url)
38
- return r.json() if r.status_code == 200 else None
39
- except: return None
40
 
41
- # 6. Main Interaction
42
- city_input = st.text_input("Search Location", placeholder="Enter City (e.g. Karachi)...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- if os.path.exists(html_path):
45
- with open(html_path, 'r', encoding='utf-8') as f:
46
- html_content = f.read()
47
 
48
- # Weather Data logic
49
- if city_input:
50
- data = get_weather(city_input)
51
- if data:
52
- # Injecting data directly into the HTML via JavaScript
53
- js_data = f"""
54
- <script>
55
- window.weatherData = {{
56
- city: "{data['name']}",
57
- temp: {round(data['main']['temp'])},
58
- condition: "{data['weather'][0]['description'].title()}"
59
- }};
60
- // Trigger React update if your app is listening to window.weatherData
61
- window.dispatchEvent(new Event('storage'));
62
- </script>
63
- """
64
- full_html = html_content + js_data
65
- components.html(full_html, height=500)
66
  else:
67
- st.error("City not found.")
68
- else:
69
- # Initial view
70
- components.html(html_content, height=500)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  else:
72
- st.error("Frontend file not found. Check if frontend/dist/index.html exists.")
73
 
74
- st.markdown("---")
75
- st.caption("Securely Powered by React + OpenWeather API")
 
1
  import streamlit as st
 
2
  import os
3
  import requests
4
+ from datetime import datetime
5
 
6
+ # 1. Page Setup
7
  st.set_page_config(page_title="SkyCast Pro", page_icon="☁️", layout="centered")
8
 
9
+ # 2. Styling (Glassmorphism Effect)
 
 
 
 
 
 
 
 
10
  st.markdown("""
11
  <style>
12
  .stApp { background-color: #0f172a; }
13
+ h1 { color: white !important; text-align: center; font-weight: 200; letter-spacing: 4px; padding-bottom: 20px; }
14
+ .weather-card {
15
+ background: rgba(255, 255, 255, 0.05);
16
+ backdrop-filter: blur(10px);
17
+ border: 1px solid rgba(255, 255, 255, 0.1);
18
+ border-radius: 20px;
19
+ padding: 30px;
20
+ color: white;
21
+ text-align: center;
22
+ margin-top: 20px;
23
  }
24
+ .temp-large { font-size: 80px; font-weight: bold; margin: 10px 0; color: #38bdf8; }
25
+ .city-name { font-size: 24px; opacity: 0.8; }
26
+ .details-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px; border-top: 1px solid rgba(255,255,255,0.1); padding-top: 20px; }
27
+ .detail-item { font-size: 14px; opacity: 0.7; }
28
+ .stTextInput>div>div>input { background: rgba(255,255,255,0.05) !important; color: white !important; border-radius: 12px !important; border: 1px solid rgba(255,255,255,0.2) !important; }
29
  </style>
30
  """, unsafe_allow_html=True)
31
 
32
  st.title("SKYCAST PRO")
33
 
34
+ # 3. Secure API Logic
35
+ API_KEY = os.environ.get('Api_key')
 
 
 
 
 
 
36
 
37
+ @st.cache_data(ttl=300) # 5 minute cache to make it faster
38
+ def get_weather(city_name):
39
+ if not API_KEY:
40
+ return {"error": "API Key missing in Secrets!"}
41
+
42
+ # solving duplicate city issue: specifying units and limit
43
+ url = f"https://api.openweathermap.org/data/2.5/weather?q={city_name}&appid={API_KEY}&units=metric"
44
+
45
+ try:
46
+ response = requests.get(url, timeout=10)
47
+ if response.status_code == 200:
48
+ return response.json()
49
+ elif response.status_code == 404:
50
+ return {"error": "City not found. Try adding country code (e.g. Hyderabad, IN or Hyderabad, PK)"}
51
+ else:
52
+ return {"error": "Weather service currently busy."}
53
+ except:
54
+ return {"error": "Connection Timeout. Please check your internet."}
55
 
56
+ # 4. Input UI
57
+ city_query = st.text_input("", placeholder="Enter City (e.g. Karachi, PK or London, UK)...")
 
58
 
59
+ if city_query:
60
+ with st.spinner("Fetching Live Data..."):
61
+ data = get_weather(city_query)
62
+
63
+ if "error" in data:
64
+ st.error(data["error"])
 
 
 
 
 
 
 
 
 
 
 
 
65
  else:
66
+ # Extracting Details
67
+ city = data['name']
68
+ country = data['sys']['country']
69
+ temp = round(data['main']['temp'])
70
+ feels_like = round(data['main']['feels_like'])
71
+ desc = data['weather'][0]['description'].title()
72
+ humidity = data['main']['humidity']
73
+ wind = data['wind']['speed']
74
+ icon = data['weather'][0]['icon']
75
+
76
+ # Weather Display Card
77
+ st.markdown(f"""
78
+ <div class="weather-card">
79
+ <div class="city-name">{city}, {country}</div>
80
+ <img src="http://openweathermap.org/img/wn/{icon}@2x.png" alt="icon">
81
+ <div class="temp-large">{temp}°C</div>
82
+ <div style="font-size: 18px; margin-bottom: 10px;">{desc}</div>
83
+ <div class="details-grid">
84
+ <div class="detail-item">
85
+ <div>FEELS LIKE</div>
86
+ <div style="color: white; font-size: 18px;">{feels_like}°C</div>
87
+ </div>
88
+ <div class="detail-item">
89
+ <div>HUMIDITY</div>
90
+ <div style="color: white; font-size: 18px;">{humidity}%</div>
91
+ </div>
92
+ <div class="detail-item">
93
+ <div>WIND SPEED</div>
94
+ <div style="color: white; font-size: 18px;">{wind} m/s</div>
95
+ </div>
96
+ <div class="detail-item">
97
+ <div>LOCAL TIME</div>
98
+ <div style="color: white; font-size: 18px;">{datetime.now().strftime('%H:%M')}</div>
99
+ </div>
100
+ </div>
101
+ </div>
102
+ """, unsafe_allow_html=True)
103
  else:
104
+ st.info("Please enter a city name to see live weather details.")
105
 
106
+ st.markdown("<br><br><p style='text-align:center; opacity:0.5; color:white; font-size:12px;'>SkyCast Pro v2.0 | Real-time Data Sync</p>", unsafe_allow_html=True)