import requests
import json
import os
import time
from datetime import datetime, timedelta
class WeatherFetcher:
def __init__(self, api_key, cache_duration_hours=1):
self.api_key = api_key
self.base_url = "http://api.openweathermap.org/data/2.5"
self.cache_file = "weather_cache.json"
self.cache_duration = timedelta(hours=cache_duration_hours)
def _load_cache(self):
"""Load cached weather data if it exists and is still valid"""
if os.path.exists(self.cache_file):
with open(self.cache_file, 'r') as f:
cache_data = json.load(f)
# Check if cache is still valid
cache_time = datetime.fromisoformat(cache_data['timestamp'])
if datetime.now() - cache_time < self.cache_duration:
return cache_data['data']
return None
def _save_cache(self, data):
"""Save weather data to cache with timestamp"""
cache_data = {
'timestamp': datetime.now().isoformat(),
'data': data
}
with open(self.cache_file, 'w') as f:
json.dump(cache_data, f)
def get_weather(self, city, units='metric'):
"""Fetch current weather for a city (with caching)"""
# Try to get from cache first
cached_data = self._load_cache()
if cached_data and cached_data.get('city') == city:
print("Using cached data")
return cached_data
# If not in cache or expired, fetch from API
try:
url = f"{self.base_url}/weather"
params = {
'q': city,
'appid': self.api_key,
'units': units
}
response = requests.get(url, params=params)
response.raise_for_status()
data = response.json()
formatted_data = {
'city': city,
'temperature': data['main']['temp'],
'feels_like': data['main']['feels_like'],
'humidity': data['main']['humidity'],
'description': data['weather'][0]['description'],
'wind_speed': data['wind']['speed'],
'timestamp': datetime.now().isoformat()
}
# Save to cache
self._save_cache(formatted_data)
return formatted_data
except requests.exceptions.RequestException as e:
print(f"Error fetching weather data: {e}")
return None
def get_forecast(self, city, units='metric'):
"""Fetch 5-day weather forecast for a city"""
try:
url = f"{self.base_url}/forecast"
params = {
'q': city,
'appid': self.api_key,
'units': units
}
response = requests.get(url, params=params)
response.raise_for_status()
data = response.json()
forecast_list = []
# Process forecast data (every 3 hours)
for item in data['list'][:8]: # Next 24 hours (8 * 3hr intervals)
forecast_list.append({
'datetime': item['dt_txt'],
'temperature': item['main']['temp'],
'description': item['weather'][0]['description'],
'wind_speed': item['wind']['speed']
})
return {
'city': city,
'forecast': forecast_list
}
except requests.exceptions.RequestException as e:
print(f"Error fetching forecast data: {e}")
return None
# Example usage
if __name__ == "__main__":
# You need to get a free API key from https://openweathermap.org/api
API_KEY = "your_api_key_here"
# Initialize the weather fetcher
weather = WeatherFetcher(API_KEY)
# Get current weather for a city
city_name = "London"
current_weather = weather.get_weather(city_name)
if current_weather:
print(f"\nCurrent Weather in {current_weather['city']}:")
print(f"Temperature: {current_weather['temperature']}°C")
print(f"Feels like: {current_weather['feels_like']}°C")
print(f"Description: {current_weather['description'].title()}")
print(f"Humidity: {current_weather['humidity']}%")
print(f"Wind Speed: {current_weather['wind_speed']} m/s")
# Get weather forecast
forecast = weather.get_forecast(city_name)
if forecast:
print(f"\n24-Hour Forecast for {forecast['city']}:")
for entry in forecast['forecast']:
print(f"{entry['datetime']}: {entry['temperature']}°C, {entry['description'].title()}")
This Python snippet creates a WeatherFetcher class that retrieves current weather conditions and forecasts from the OpenWeatherMap API. It includes intelligent caching to avoid unnecessary API calls and provides formatted weather data suitable for applications.
Key features:
Many applications need weather information but making constant API requests is inefficient and may exceed rate limits. This implementation:
"your_api_key_here" with your actual API keypip install requestsget_weather(city_name) for current conditionsget_forecast(city_name) for future predictionsThe caching feature automatically stores weather data for 1 hour (configurable) to minimize API calls while ensuring reasonably fresh information.