Spaces:
Sleeping
Sleeping
File size: 5,902 Bytes
77b0eff 187fcd9 1e25fc9 187fcd9 b0b1de3 187fcd9 b0b1de3 77b0eff 187fcd9 b0b1de3 187fcd9 77b0eff 1e25fc9 77b0eff b0b1de3 77b0eff 187fcd9 77b0eff 187fcd9 77b0eff 187fcd9 77b0eff 26e237b 77b0eff 26e237b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import dash
from dash import dcc, html, Input, Output
import plotly.graph_objs as go
import requests
import os
from datetime import datetime
# Inline weather_model.py with fixes
def get_weather_data(city, days, api_key):
try:
# Fallback to coordinates if city name fails
city_coords = {
"Hyderabad": {"lat": 17.3850, "lon": 78.4867},
"Gadwal": {"lat": 16.2350, "lon": 77.8050},
"Bengaluru": {"lat": 12.9716, "lon": 77.5946}
}
coords = city_coords.get(city)
if not coords:
geo_url = f"http://api.openweathermap.org/geo/1.0/direct?q={city}&limit=1&appid={api_key}"
geo_response = requests.get(geo_url).json()
if not geo_response:
return None
coords = {"lat": geo_response[0]['lat'], "lon": geo_response[0]['lon']}
url = f"http://api.openweathermap.org/data/2.5/onecall?lat={coords['lat']}&lon={coords['lon']}&exclude=minutely,hourly&units=metric&appid={api_key}"
response = requests.get(url, timeout=10).json()
current = {
'temp': response['current']['temp'],
'weather': response['current']['weather'][0]['description'],
'humidity': response['current']['humidity'],
'wind_speed': response['current']['wind_speed']
}
forecast = []
for i in range(min(days, len(response['daily']))):
day = response['daily'][i]
forecast.append({
'date': datetime.fromtimestamp(day['dt']).strftime('%Y-%m-%d'),
'temp': day['temp']['day'],
'precipitation': day.get('rain', 0) + day.get('snow', 0),
'wind_speed': day['wind_speed'],
'weather': day['weather'][0]['main']
})
return {'current': current, 'forecast': forecast}
except requests.exceptions.RequestException as e:
print(f"Network error for {city}: {e}")
return None
except KeyError as e:
print(f"API response error for {city}: {e}")
return None
except Exception as e:
print(f"Unexpected error for {city}: {e}")
return None
# Initialize Dash app
app = dash.Dash(__name__)
app.title = "Weather Forecast Dashboard"
# Use environment variable for API key
API_KEY = os.getenv("OPENWEATHERMAP_API_KEY", "53d50455f91b6bc3c920959e2954576d")
# Fixed locations
LOCATIONS = ["Hyderabad", "Gadwal", "Bengaluru"]
DAYS = 5 # Fixed 5-day forecast
# Layout
app.layout = html.Div([
html.Div([
html.H1("Weather Forecast Dashboard", style={'textAlign': 'center', 'color': '#FFFFFF'}),
html.P("Current weather for Hyderabad, Gadwal, and Bengaluru (Karnataka).",
style={'textAlign': 'center', 'color': '#D3D9D4'})
], style={'backgroundColor': '#212A31', 'padding': '20px'}),
html.Div([
html.H2("Weather Overview", style={'color': '#FFFFFF', 'padding': '10px'}),
html.Div(id='weather-display', style={'display': 'flex', 'flexWrap': 'wrap', 'justifyContent': 'space-around'})
], style={'backgroundColor': '#2E3944', 'padding': '20px', 'borderRadius': '10px'}),
], style={'backgroundColor': '#1A2329', 'fontFamily': 'Arial', 'minHeight': '100vh'})
# Callback to update dashboard
@app.callback(
Output('weather-display', 'children'),
Input('weather-display', 'id') # Dummy input to trigger on load
)
def update_dashboard(_):
weather_components = []
for city in LOCATIONS:
weather_data = get_weather_data(city, DAYS, API_KEY)
if not weather_data:
weather_components.append(
html.Div(f"Error: Could not fetch data for {city}", style={'color': '#FF5555', 'padding': '10px'})
)
continue
current = weather_data['current']
forecast = weather_data['forecast']
# Text Summary
summary = html.Div([
html.H3(f"{city}", style={'color': '#FFFFFF'}),
html.P(f"Current Temp: {current['temp']}°C", style={'color': '#D3D9D4'}),
html.P(f"Condition: {current['weather']}", style={'color': '#D3D9D4'}),
html.P(f"Humidity: {current['humidity']}%", style={'color': '#D3D9D4'}),
html.P(f"Wind Speed: {current['wind_speed']} km/h", style={'color': '#D3D9D4'}),
], style={'width': '30%', 'padding': '10px'})
# Donut Charts
temp_values = [f['temp'] for f in forecast]
temp_fig = go.Figure(data=[go.Pie(labels=[f['date'] for f in forecast], values=temp_values, hole=.3)])
temp_fig.update_layout(title=f"{city} - Temperature (°C)", template='plotly_dark')
precip_values = [f['precipitation'] for f in forecast]
precip_fig = go.Figure(data=[go.Pie(labels=[f['date'] for f in forecast], values=precip_values, hole=.3)])
precip_fig.update_layout(title=f"{city} - Precipitation (mm)", template='plotly_dark')
wind_values = [f['wind_speed'] for f in forecast]
wind_fig = go.Figure(data=[go.Pie(labels=[f['date'] for f in forecast], values=wind_values, hole=.3)])
wind_fig.update_layout(title=f"{city} - Wind Speed (km/h)", template='plotly_dark')
# Combine into a city section
city_section = html.Div([
summary,
dcc.Graph(figure=temp_fig, style={'width': '20%', 'display': 'inline-block'}),
dcc.Graph(figure=precip_fig, style={'width': '20%', 'display': 'inline-block'}),
dcc.Graph(figure=wind_fig, style={'width': '20%', 'display': 'inline-block'}),
], style={'margin': '20px', 'backgroundColor': '#2E3944', 'borderRadius': '10px', 'padding': '10px'})
weather_components.append(city_section)
return weather_components
# Run server on port 7860 for Hugging Face Spaces
if __name__ == '__main__':
app.run_server(debug=True, host='0.0.0.0', port=7860) |