Skip to content

Commit 70d673f

Browse files
authored
Update current_weather.py
1 parent 52602ea commit 70d673f

File tree

1 file changed

+64
-26
lines changed

1 file changed

+64
-26
lines changed

web_programming/current_weather.py

+64-26
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,88 @@
1+
import os
12
import requests
3+
import asyncio
4+
import aiohttp
5+
import json
6+
from pprint import pprint
7+
from datetime import datetime, timedelta
28

3-
# Put your API key(s) here
4-
OPENWEATHERMAP_API_KEY = ""
5-
WEATHERSTACK_API_KEY = ""
9+
# Load API keys from environment variables
10+
OPENWEATHERMAP_API_KEY = os.getenv("OPENWEATHERMAP_API_KEY")
11+
WEATHERSTACK_API_KEY = os.getenv("WEATHERSTACK_API_KEY")
612

7-
# Define the URL for the APIs with placeholders
13+
# Define the URL for the APIs
814
OPENWEATHERMAP_URL_BASE = "https://api.openweathermap.org/data/2.5/weather"
915
WEATHERSTACK_URL_BASE = "http://api.weatherstack.com/current"
1016

17+
# Cache to store recent responses
18+
cache = {}
19+
CACHE_DURATION = timedelta(minutes=5) # Cache duration
1120

12-
def current_weather(location: str) -> list[dict]:
21+
22+
async def fetch_weather(session, url, params):
23+
async with session.get(url, params=params) as response:
24+
response.raise_for_status() # Raises an error for bad responses
25+
return await response.json()
26+
27+
28+
async def current_weather(location: str) -> list[dict]:
1329
"""
14-
>>> current_weather("location")
15-
Traceback (most recent call last):
16-
...
17-
ValueError: No API keys provided or no valid data returned.
30+
Fetch current weather data from OpenWeatherMap and WeatherStack asynchronously.
31+
32+
Raises:
33+
ValueError: If no API keys are provided or no valid data is returned.
34+
35+
Returns:
36+
A list of dictionaries containing weather data.
1837
"""
38+
if not OPENWEATHERMAP_API_KEY and not WEATHERSTACK_API_KEY:
39+
raise ValueError("No API keys provided.")
40+
41+
if location in cache and datetime.now() < cache[location]['expires']:
42+
return cache[location]['data']
43+
1944
weather_data = []
20-
if OPENWEATHERMAP_API_KEY:
21-
params_openweathermap = {"q": location, "appid": OPENWEATHERMAP_API_KEY}
22-
response_openweathermap = requests.get(
23-
OPENWEATHERMAP_URL_BASE, params=params_openweathermap, timeout=10
24-
)
25-
weather_data.append({"OpenWeatherMap": response_openweathermap.json()})
26-
if WEATHERSTACK_API_KEY:
27-
params_weatherstack = {"query": location, "access_key": WEATHERSTACK_API_KEY}
28-
response_weatherstack = requests.get(
29-
WEATHERSTACK_URL_BASE, params=params_weatherstack, timeout=10
30-
)
31-
weather_data.append({"Weatherstack": response_weatherstack.json()})
45+
async with aiohttp.ClientSession() as session:
46+
tasks = []
47+
48+
if OPENWEATHERMAP_API_KEY:
49+
params_openweathermap = {"q": location, "appid": OPENWEATHERMAP_API_KEY}
50+
tasks.append(fetch_weather(session, OPENWEATHERMAP_URL_BASE, params_openweathermap))
51+
52+
if WEATHERSTACK_API_KEY:
53+
params_weatherstack = {"query": location, "access_key": WEATHERSTACK_API_KEY}
54+
tasks.append(fetch_weather(session, WEATHERSTACK_URL_BASE, params_weatherstack))
55+
56+
responses = await asyncio.gather(*tasks, return_exceptions=True)
57+
58+
for i, response in enumerate(responses):
59+
if isinstance(response, Exception):
60+
print(f"Error fetching data: {response}")
61+
continue
62+
weather_data.append(response)
63+
3264
if not weather_data:
33-
raise ValueError("No API keys provided or no valid data returned.")
65+
raise ValueError("No valid data returned.")
66+
67+
# Cache the response
68+
cache[location] = {
69+
'data': weather_data,
70+
'expires': datetime.now() + CACHE_DURATION
71+
}
72+
3473
return weather_data
3574

3675

3776
if __name__ == "__main__":
38-
from pprint import pprint
39-
4077
location = "to be determined..."
4178
while location:
4279
location = input("Enter a location (city name or latitude,longitude): ").strip()
4380
if location:
4481
try:
45-
weather_data = current_weather(location)
82+
weather_data = asyncio.run(current_weather(location))
4683
for forecast in weather_data:
4784
pprint(forecast)
4885
except ValueError as e:
4986
print(repr(e))
50-
location = ""
87+
except Exception as e:
88+
print(f"An unexpected error occurred: {repr(e)}")

0 commit comments

Comments
 (0)