Files
lab_weather/weather/weather_apis.py
2025-12-10 09:43:47 -05:00

88 lines
2.6 KiB
Python

import requests
# -----------------------------------------------------------
# Geocode a text location (EX: "Boston, MA") using Nominatim
# -----------------------------------------------------------
def geocode_location(location):
url = "https://nominatim.openstreetmap.org/search"
params = {
"q": location,
"format": "json",
"limit": 1
}
response = requests.get(url, params=params, timeout=5)
data = response.json()
if not data:
raise ValueError(f"Could not geocode location: {location}")
return {
"lat": float(data[0]["lat"]),
"lng": float(data[0]["lon"])
}
# -----------------------------------------------------------
# Estimate user's coordinates using IP geolocation
# -----------------------------------------------------------
def estimate_location():
"""Estimate user's location using IP-based geolocation."""
try:
response = requests.get("https://ipinfo.io/json", timeout=5)
data = response.json()
if "loc" not in data:
raise RuntimeError("IP lookup returned no coordinates.")
lat_str, lng_str = data["loc"].split(",")
return {
"lat": float(lat_str),
"lng": float(lng_str)
}
except Exception as e:
raise RuntimeError(f"Could not estimate location: {e}")
# -----------------------------------------------------------
# Get the nearest weather office from NOAA API
# -----------------------------------------------------------
def get_weather_office(lat, lng):
url = f"https://api.weather.gov/points/{lat},{lng}"
response = requests.get(url, timeout=5)
data = response.json()
props = data["properties"]
return {
"office": props["gridId"],
"x": props["gridX"],
"y": props["gridY"]
}
# -----------------------------------------------------------
# Get NOAA forecast
# -----------------------------------------------------------
def get_forecast(office, x, y, metric=False):
url = f"https://api.weather.gov/gridpoints/{office}/{x},{y}/forecast"
response = requests.get(url, timeout=5)
data = response.json()
periods = data["properties"]["periods"]
# Convert NOAA data to your class format
forecast = []
for p in periods:
forecast.append({
"name": p["name"],
"description": p["detailedForecast"],
"temperature": p["temperature"] if not metric else round((p["temperature"] - 32) * 5/9),
"wind_speed": p["windSpeed"],
"wind_direction": p["windDirection"]
})
return forecast