Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import requests | |
| import pandas as pd | |
| import plotly.express as px | |
| from datetime import datetime | |
| # Page configuration | |
| st.set_page_config( | |
| page_title="WeatherFlow | Real-Time Dashboard", | |
| page_icon="🌤️", | |
| layout="wide" | |
| ) | |
| # FIXED CSS: Modern "Glassmorphism" style that works in Light and Dark mode | |
| st.markdown(""" | |
| <style> | |
| /* Targets the metric cards specifically */ | |
| [data-testid="stMetric"] { | |
| background-color: rgba(120, 120, 120, 0.1); /* Semi-transparent */ | |
| border: 1px solid rgba(120, 120, 120, 0.3); | |
| padding: 15px; | |
| border-radius: 12px; | |
| } | |
| /* Ensures the city header stands out */ | |
| .city-header { | |
| font-size: 2.5rem; | |
| font-weight: 800; | |
| color: #3366ff; | |
| } | |
| footer {visibility: hidden;} | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Helper function to translate WMO codes to words | |
| def decode_weather(code): | |
| mapping = { | |
| 0: "Clear Sky", 1: "Mainly Clear", 2: "Partly Cloudy", 3: "Overcast", | |
| 45: "Fog", 48: "Depositing Rime Fog", 51: "Light Drizzle", | |
| 61: "Slight Rain", 71: "Slight Snow", 95: "Thunderstorm" | |
| } | |
| return mapping.get(code, "Cloudy") # Default to Cloudy if code is unknown | |
| def get_weather_data(city): | |
| geo_url = f"https://geocoding-api.open-meteo.com/v1/search?name={city}&count=1&language=en&format=json" | |
| response = requests.get(geo_url) | |
| if response.status_code == 200 and "results" in response.json(): | |
| data = response.json()["results"][0] | |
| return data["latitude"], data["longitude"], data.get("country", ""), data.get("name", "") | |
| return None | |
| st.title("🌤️ WeatherFlow Dashboard") | |
| city_input = st.text_input("Enter city (e.g., Muzaffargarh, London, Tokyo):", "Muzaffargarh") | |
| if city_input: | |
| location = get_weather_data(city_input) | |
| if location: | |
| lat, lon, country, city_name = location | |
| weather_url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}¤t_weather=true&hourly=temperature_2m,relative_humidity_2m&timezone=auto" | |
| w_res = requests.get(weather_url).json() | |
| current = w_res["current_weather"] | |
| # UI: Header | |
| st.markdown(f"<p class='city-header'>{city_name}, {country}</p>", unsafe_allow_html=True) | |
| # UI: Metrics Section (High Contrast) | |
| m1, m2, m3, m4 = st.columns(4) | |
| m1.metric("Temperature", f"{current['temperature']}°C") | |
| m2.metric("Wind Speed", f"{current['windspeed']} km/h") | |
| # Now decodes the number into a readable condition | |
| m3.metric("Condition", decode_weather(current['weathercode'])) | |
| m4.metric("Timezone", w_res["timezone_abbreviation"]) | |
| # UI: Chart | |
| st.markdown("### 📈 24-Hour Temperature Forecast") | |
| hourly_data = w_res["hourly"] | |
| df = pd.DataFrame({ | |
| "Time": pd.to_datetime(hourly_data["time"][:24]), | |
| "Temp (°C)": hourly_data["temperature_2m"][:24] | |
| }) | |
| fig = px.area(df, x="Time", y="Temp (°C)", color_discrete_sequence=['#3366ff']) | |
| fig.update_layout(margin=dict(l=0, r=0, t=20, b=0), height=300) | |
| st.plotly_chart(fig, use_container_width=True) | |
| else: | |
| st.error("City not found. Check your spelling!") | |
| st.markdown("---") | |
| st.markdown(f"<center><small>WeatherFlow v1.0 | {datetime.now().year}</small></center>", unsafe_allow_html=True) |