bluenevus commited on
Commit
c857657
·
verified ·
1 Parent(s): a1eee9d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +162 -12
app.py CHANGED
@@ -23,7 +23,6 @@ API_KEY = os.getenv('ACCUWEATHER_API_KEY')
23
  # Base URL for AccuWeather API
24
  BASE_URL = "http://dataservice.accuweather.com"
25
 
26
- # Define all the necessary functions
27
  def get_location_key(lat, lon):
28
  url = f"{BASE_URL}/locations/v1/cities/geoposition/search"
29
  params = {
@@ -42,20 +41,133 @@ def get_location_key(lat, lon):
42
  return None
43
 
44
  def get_current_conditions(location_key):
45
- # Implementation as before
46
- ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  def get_forecast(location_key):
49
- # Implementation as before
50
- ...
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  def get_indices(location_key):
53
- # Implementation as before
54
- ...
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  def get_alerts(location_key):
57
- # Implementation as before
58
- ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
  # App layout
61
  app.layout = dbc.Container([
@@ -121,10 +233,48 @@ def update_weather(location):
121
 
122
  lat, lon = location["latitude"], location["longitude"]
123
 
124
- # Rest of the function remains the same
125
- ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
- # The rest of the code (create_current_weather_card, create_forecast_card, etc.) remains the same
 
128
 
129
  if __name__ == '__main__':
130
  print("Starting the Dash application...")
 
23
  # Base URL for AccuWeather API
24
  BASE_URL = "http://dataservice.accuweather.com"
25
 
 
26
  def get_location_key(lat, lon):
27
  url = f"{BASE_URL}/locations/v1/cities/geoposition/search"
28
  params = {
 
41
  return None
42
 
43
  def get_current_conditions(location_key):
44
+ if location_key is None:
45
+ return None
46
+ url = f"{BASE_URL}/currentconditions/v1/{location_key}"
47
+ params = {
48
+ "apikey": API_KEY,
49
+ "details": "true",
50
+ }
51
+ try:
52
+ response = requests.get(url, params=params)
53
+ response.raise_for_status()
54
+ data = response.json()
55
+ if not data:
56
+ raise ValueError("No current conditions data in API response")
57
+ return data[0]
58
+ except requests.RequestException as e:
59
+ print(f"Error in get_current_conditions: {e}")
60
+ return None
61
 
62
  def get_forecast(location_key):
63
+ if location_key is None:
64
+ return None
65
+ url = f"{BASE_URL}/forecasts/v1/daily/5day/{location_key}"
66
+ params = {
67
+ "apikey": API_KEY,
68
+ "metric": "true",
69
+ }
70
+ try:
71
+ response = requests.get(url, params=params)
72
+ response.raise_for_status()
73
+ return response.json()
74
+ except requests.RequestException as e:
75
+ print(f"Error in get_forecast: {e}")
76
+ return None
77
 
78
  def get_indices(location_key):
79
+ if location_key is None:
80
+ return None
81
+ url = f"{BASE_URL}/indices/v1/daily/5day/{location_key}"
82
+ params = {
83
+ "apikey": API_KEY,
84
+ }
85
+ try:
86
+ response = requests.get(url, params=params)
87
+ response.raise_for_status()
88
+ return response.json()
89
+ except requests.RequestException as e:
90
+ print(f"Error in get_indices: {e}")
91
+ return None
92
 
93
  def get_alerts(location_key):
94
+ if location_key is None:
95
+ return None
96
+ url = f"{BASE_URL}/alerts/v1/{location_key}"
97
+ params = {
98
+ "apikey": API_KEY,
99
+ }
100
+ try:
101
+ response = requests.get(url, params=params)
102
+ response.raise_for_status()
103
+ return response.json()
104
+ except requests.RequestException as e:
105
+ print(f"Error in get_alerts: {e}")
106
+ return None
107
+
108
+ def create_current_weather_card(current):
109
+ return dbc.Card([
110
+ dbc.CardBody([
111
+ html.H4("Current Weather", className="card-title"),
112
+ html.P(f"Temperature: {current['Temperature']['Metric']['Value']}°C"),
113
+ html.P(f"Condition: {current['WeatherText']}"),
114
+ html.P(f"Feels Like: {current['RealFeelTemperature']['Metric']['Value']}°C"),
115
+ html.P(f"Wind: {current['Wind']['Speed']['Metric']['Value']} km/h"),
116
+ html.P(f"Humidity: {current['RelativeHumidity']}%"),
117
+ ])
118
+ ], className="mb-4")
119
+
120
+ def create_forecast_card(forecast):
121
+ daily_forecasts = forecast['DailyForecasts']
122
+
123
+ fig = go.Figure()
124
+
125
+ dates = [datetime.strptime(day['Date'], "%Y-%m-%dT%H:%M:%S%z").strftime("%m-%d") for day in daily_forecasts]
126
+ max_temps = [day['Temperature']['Maximum']['Value'] for day in daily_forecasts]
127
+ min_temps = [day['Temperature']['Minimum']['Value'] for day in daily_forecasts]
128
+
129
+ fig.add_trace(go.Scatter(x=dates, y=max_temps, name="Max Temp", line=dict(color="red")))
130
+ fig.add_trace(go.Scatter(x=dates, y=min_temps, name="Min Temp", line=dict(color="blue")))
131
+
132
+ fig.update_layout(
133
+ title="5-Day Temperature Forecast",
134
+ xaxis_title="Date",
135
+ yaxis_title="Temperature (°C)",
136
+ legend_title="Temperature",
137
+ height=400
138
+ )
139
+
140
+ return dbc.Card([
141
+ dbc.CardBody([
142
+ html.H4("5-Day Forecast", className="card-title"),
143
+ dcc.Graph(figure=fig)
144
+ ])
145
+ ], className="mb-4")
146
+
147
+ def create_indices_card(indices):
148
+ return dbc.Card([
149
+ dbc.CardBody([
150
+ html.H4("Weather Indices", className="card-title"),
151
+ html.Div([
152
+ html.P(f"{index['Name']}: {index['Category']}")
153
+ for index in indices[:5] # Display first 5 indices
154
+ ])
155
+ ])
156
+ ], className="mb-4")
157
+
158
+ def create_alert_card(alerts):
159
+ if not alerts:
160
+ return html.Div()
161
+
162
+ return dbc.Card([
163
+ dbc.CardBody([
164
+ html.H4("Weather Alerts", className="card-title text-danger"),
165
+ html.Div([
166
+ html.P(alert['Text'])
167
+ for alert in alerts
168
+ ])
169
+ ])
170
+ ], className="mb-4")
171
 
172
  # App layout
173
  app.layout = dbc.Container([
 
233
 
234
  lat, lon = location["latitude"], location["longitude"]
235
 
236
+ loading_output = html.Div([
237
+ html.P("Loading weather data...", className="text-center"),
238
+ dbc.Spinner(color="primary", type="grow"),
239
+ ])
240
+
241
+ def fetch_weather_data():
242
+ try:
243
+ location_key = get_location_key(lat, lon)
244
+ if location_key is None:
245
+ raise ValueError("Failed to get location key")
246
+
247
+ current = get_current_conditions(location_key)
248
+ forecast = get_forecast(location_key)
249
+ indices = get_indices(location_key)
250
+ alerts = get_alerts(location_key)
251
+
252
+ if current is None or forecast is None or indices is None:
253
+ raise ValueError("Failed to fetch weather data")
254
+
255
+ current_weather = create_current_weather_card(current)
256
+ forecast_output = create_forecast_card(forecast)
257
+ indices_output = create_indices_card(indices)
258
+ alert_output = create_alert_card(alerts)
259
+
260
+ return current_weather, forecast_output, indices_output, alert_output
261
+
262
+ except Exception as e:
263
+ error_message = f"Error fetching weather data: {str(e)}"
264
+ print(error_message) # Log the error
265
+ return "", "", "", html.Div(error_message, className="text-danger")
266
+
267
+ # Use threading to fetch data asynchronously
268
+ thread = threading.Thread(target=fetch_weather_data)
269
+ thread.start()
270
+ thread.join(timeout=10) # Wait for up to 10 seconds
271
+
272
+ if thread.is_alive():
273
+ error_message = "Weather data fetch timed out. Please try again."
274
+ return html.Div(error_message, className="text-warning"), "", "", "", ""
275
 
276
+ current_weather, forecast_output, indices_output, alert_output = fetch_weather_data()
277
+ return "", current_weather, forecast_output, indices_output, alert_output
278
 
279
  if __name__ == '__main__':
280
  print("Starting the Dash application...")